Using git-ftp for project deployment

Combining the usefulness and efficiency of Git version control with a simple and straightforward FTP deployment method

A vital part of any project comes at the end when you need to push all of your code and assets onto a live server, and publish your work. Not only that, but you need to ensure that further bug-fixes and feature requests can be deployed easily too.

Especially if you’re limited to only FTP or SFTP access on your deployment server, you can quickly find the constant development/deployment cycle taking up a lot of time as you try to keep on top of what’s changed locally against what’s changed remotely.

Some things to consider when setting a project live:

  • How are the assets distributed? Are they spread between a filesystem and a database?
  • What access do you have to the production server? (Shell access, or just FTP?)
  • How do you track your source code, is it version controlled?

In my case, I keep all of my code versioned within a Git repository. And if a project consists purely of file-based content, this simplifies things and you may find the following solution of use.

git-ftp is an FTP client written as a shell script, so that it can be executed from the command line, and deploys directly via FTP, transferring only the recently modified files and leaving all others untouched, unless explicitly instructed otherwise.

Your server environment

Depending on the specifics of your project and your server configuration, you may not have full access to root-level features such as shell access. This can be the case if your deployment location is hosted on a shared server environment, or otherwise locked down system. This usually means that you won’t have access to tools such as the command-line git tool which could otherwise be utilised to deploy project files.

If that’s the case, then it’s likely that the only direct access you’ll have to the filesystem is via a (S)FTP connection.

This solution deals with cases where you are both:

  • Tracking your project’s files within a git repository
  • Limited to using only FTP or SFTP on your deployment server

Enter git-ftp

You can find everything required to install and configure git-ftp over on its Git page here.

Initial setup is straightforward - once installed in a suitable location (on my Windows machine, for example, I have it installed within a Git shell) you can store the appropriate configuration settings within your project’s .git/config file. This means that you can store all of your project deployment settings, and track them via version control. Very handy!

Configuration is straightforward. You can see plenty of examples on the man page here

For example, to set the username, FTP address and password,

$ git config git-ftp.user robin
$ git config git-ftp.url ftp.solarisedesign.co.uk
$ git config git-ftp.password yeahLikeIdPutThatHere

There are other settings, detailed on the man page, which concern SFTP authentication and SSH keys which you can set up to avoid sending details over an insecure connection.

Once configured, the process is fairly straightforward and can be initiated via the command line with the git ftp command.

  1. git-ftp checks your local repository for changes. If any are found, it prepares the transfer
  2. By comparing your latest commit with the most recent commit uploaded via FTP (by utilising a log file stored on the server), git-ftp knows which files have been modified or deleted since the last transfer
  3. git-ftp transfers any changed or new files, and deletes any old ones on the remote server.

For example, say you have the following files in your project

file1.txt
file2.php
file3.jpg

You run an initial transfer by executing the command,

git ftp init -v

This prepares the remote deployment location by initially uploading all files from the repository, regardless of their change status. The -v flag is there to provide additional feedback information, otherwise I found that for large uploads, the lack of progress information means it’s difficult to gauge how long the proess will take.

Transfer [file1.txt, file2.php, file3.jpg] --> remote server

Along with your files, git-ftp also uploads a log file containing the SHA hash of your latest commit.

Then say we modify some of our files,

file1.txt
*file2.php* [modified]
~file3.jpg~ [deleted]

Now, we run the command,

git ftp push -v

This then checks the uploaded log file on the server to determine what, if anything, has changed since the last transfer. It should see that file2.php has been changed and file3.jpg has been deleted. It then connects via FTP again and transfers the new file2.php and deletes the remote copy of file3.jpg

Transfer [file2.php] --> remove server, Delete [file3.jpg]

Other useful features

There are some other aspects of git-ftp which could come in handy for more complex projects

  • The .git-ftp-ignore and .git-ftp-include files. These two files can be used to ignore, and include respectively, files in your project that you either want to leave out of the FTP transfer (e.g. environment-specific configuration settings) or include if they aren’t part of your git repository
  • Scopes, a useful way of setting up multiple different environments within a single project. Useful if you want to run both a live and a test deployment.

Check out the man page for more details.

Limitations

There are a couple of limitations when using this method,

  • You can’t modify files directly on the server using S(FTP) if you’re using this method. Any changes have to be made locally, commited to the repository and then transferred via git-ftp. Any changes that are made run the risk of putting the site out of sync with the repository
  • This may not work for large teams. It’s important that no new code is commited to the repository while a transfer is taking place. Again, this can throw the site out of sync. If the entire team is happy with this method though, and is using Git to track all changes, then it may work well.

Also, it’s not so much a limitation, but this process requires that you have commited all changes to your git repository prior to running the command. This could be a little frustrating initially if you’re not accustomed to frequently commiting your code and need to test frequently on the remote deployment server, but I find it’s a useful reminder to commit often, and gets you into good practice.

This method also wouldn’t cover content if your site is powered by a database (although this is a problem common to deployment and maintenance with any site that runs a backend database anyway - you’d need to look at more thorough tools to manage database deployment cleanly)

My own site is powered by Statamic, an entirely file-based system, so I find this git-ftp deployment method to be a really nice fit. Especially as it’s just myself working on it, it’s a real timesaver - and good practice - to be able to commit the latest changes and throw everything up immediately to the server with a single command.

Generally speaking, I find git-ftp a very useful tool to ease my deployment process. For my purposes if provides everything I need it to, and I’d likely consider using it on projects with small teams too.


If this is the sort of thing that you think may benefit your own project, feel free to get in touch to ask me any questions you might have.

Next Article »