From FTP to Git: A Deployment Story

Once upon a time, there was a file. It was on your computer, and you wanted to get it on a server.

Ever wondered why there are so many ways to do that? We'll explain some of the basics of deployment in this article so you understand when to use what. Let's get started!

FTP

FTP, or File Transfer Protocol, is considered by many people to be the old school way to "put a site up." It is a protocol, which basically means that there are a set of rules that both the local computer and the host machine agree on, and can send messages through. FTP is not a "program," per se, but rather more like a phone line.

SFTP/SSH

So, if FTP is an old-school phone line (that still works just fine), SFTP is like a 4G network

It offers a new protocol for the two machines to talk (not that it is necessarily faster, however). SFTP is powered by SSH, which essentially encrypts the messages that are passed between the two machines; so any malicious third-party or untrusted network can't get a hold of your raw data during the transfer.

SFTP vs FTP

If you didn't quite catch that, FTP and SFTP are both file transfer protocols. However, SFTP (and other SSH-powered transfer protocols) transfers files and encrypts the transfer. "I don't need encryption", you may say. A lot of people think the same way; however, forward-thinking developers and modern tools will lean towards more secure methods. You've heard it before - Better safe than sorry.

But I don't feel like going through the trouble.

First of all, if this is your job, suck it up. You can either stick with your comfort zone (you know, FTP still works, just like your landline phone). But don't you want to get better? After all, that's why you're here, right?

Now, if you are still a little lazy but like the idea of easy adoption, you can use SFTP with almost any FTP client out there. It's more secure. Make sure your server supports SSH (port 22, commonly, needs to be open), and you should be good to go. But the point of this article isn't to get you thinking about encryption and transfer security; it's to get you thinking about a more robust deployment strategy.

Deployment vs File Transfer

"But I don't feel like going through the trouble." ...if this is your job, suck it up

If you've been developing for a while, you've probably gone through the drill of creating a site and constantly dragging and dropping your files to your FTP client (or double-clicking, or pressing "sync", or...). This is technically a deployment strategy, albeit not a very robust one. Of course, a lot of times this kind of strategy will work fine, especially if you're the only person that will ever touch the files, and you've magically never overwritten or deleted an important file. But, again, you're here to get better, right? And you are a magician.

Deployment, in its simplest form, is taking some code and making it "live" code. By transferring an index.html file into your serving directory, you are deploying. In fact, at the end of the day, all deployment strategies (unless you are using a compiled app system) essentially move files or versions of files into the "current working directory", or change the ones that are already there. For instance, you could make changes to that same index.html file directly on the server, and that would effectively "deploy" those changes to the public. But deployment can be a lot more.

Has your team ever set up a system that requires you to notify everyone when you have pushed a file onto the server through FTP? Or maybe you have to restart a Django or Rails server after changing code. If you do this as a part of the routine of making your site reflect the changes you've made, that is part of your deployment process.

Version Control Concepts

So, if deployment means making some set of code and files live, how can there be much more than SFTP? "What is Git, and why should you care?" you're asking. Git is a Version Control System, or a VCS. It is one of many VCSs that we've shamelessly picked as our favorite. We'll explain why later, but first let's talk about what it is.

Version control systems accomplish a lot of tasks, but the most important is providing a safety net to developers--especially development teams. We mentioned earlier how FTP and SFTP may be perfectly fine if you're perfect and you'll never overwrite a file or delete an important folder unintentionally. But if you haven't done this yet, don't worry - it will happen sooner or later. It's almost certain that it has happened to your team if you haven't figured out a workaround system. But even those workaround systems are a pain. For instance, has your CSS directory ever looked like this?

If so, you're keeping versions of stylesheets that eventually you will merge together. Incidentally, Git does this, but it does it a lot better, faster, and more robustly than you can on your own. Do you keep a different CSS file every time you make a few changes? Just in case you want to come back to exactly how that file was at a certain point in time? Of course you don't. But Git will do exactly that for you, and you don't have a mess of strewn files and obscure naming systems everywhere. Beyond this, Git is smart enough to know how to take your styles.css file and merge it with Mary or John's styles.css file. Furthermore, Git's versions are not entire files; instead, they are stored in deltas, which is essentially a low-level code representation of the differences between one file and another file. This means that different versions are much smaller, and much faster to transfer when it comes time to deploy them.

But none of this has anything to do with deployment, you say? You're right, version control systems in large part simply do what their name suggests: keep versions in order. But, they also have the ability to communicate through the different protocols we've discussed before. Git can read through HTTP and read and write through SSH. (Read more about the transfer protocols here.)

So if Git has these direct connections through transfer protocols, you can push versions back and forth with your team through a local server, GitHub, or your own live server. And that's how Git fits into deployment. You push your code, Mary and John push their code, then whoever is in charge of deployment on your team will log onto the server and merge the code into the live environment. Git offers the ability to have multiple destinations and branches of code to push different versions to different places. A common practice is to have a "staging" server, where code is pushed to check it in a live environment on a private development domain. Another possible workflow is to never connect your team's local repositories to the live repository, and instead only allow the staging machine the ability to push to the live server. This creates a system for review that can't be skipped.

Different versions are much smaller, and much faster to transfer, when it comes time to deploy them.

Beyond staging, branches, multiple deployment destinations, and robust version control, Git offers hooks, like "post-receive", that can perform any kind of action you can throw together. Maybe you want a "spider" branch, where when the code arrives at one point on your server, the post receive pushes that code across multiple locations (remote or otherwise). Even further, using a platform like GitHub offers a great graphical interface for setting up hooks. Easily tell GitHub to send you emails (or if you're creative, hook up a Growl notification) every time you receive a push from a team member, for instance.

There are literally thousands of ways to develop a deployment strategy with Git. You can quickly see that using a VCS for deployment offers some very extensive advantages, protection, and power to your deployment. Once you take the time to learn enough about Git to get a workflow in place (and make a few mistakes with it), your development process will benefit immensely.

Deploying with Git: A Barebones Example

The following commands will set up a repository on a remote machine, set up a repository on your local machine, adding the remote repository as "origin", checkout a branch called "mybranch" that will be merged on the server, pushes "mybranch" to the remote, "origin", and finally logs back on to the server to merge "mybranch" with the default "master" branch.

Git + Heroku: A Match Made In the Clouds

Beyond making your own Git-powered workflow and integrating it into your own server, you can utilize other free services, such as Heroku;. Heroku is a hosting solution that allows you to run a few lines from your Git-controlled app, and deploy it to the "cloud" (in this case, a remote cluster of Linux servers) over Git with almost no effort. Take a few minutes to get a few things configured, and you're off to the races with just a few lines of code for simple deployment. Seriously, it looks something like this.

# do some work, keep it version-controlled with Git... then
> heroku create --stack cedar
# the --stack cedar basically allows you to create multiple kinds of apps, including PHP and Node
# ... Heroku will tell you it's creating things, then it will tell you it added a heroku remote to your git repo
> git push heroku master
# and that's it! Open the deployed app in your browser
> heroku open

Other similar tools include Pagoda Box, which is focused on LAMP-based architectures, and AppFog and PHPFog, which is very similar to Heroku.

As long as there aren't any errors in your configuration and you've followed Heroku's guidelines for how to set up apps, you can have Rails, PHP, or Node apps up and running in a few moments. Oh, and did we mention that you can make simple Heroku-powered apps for free? It's not until you upgrade to more instances or memory, or need to add a database, that you incur charges from Heroku. Other similar tools include Pagoda Box, which is focused on LAMP-based architectures, and AppFog and PHPFog, which is very similar to Heroku. These options offer similar services and Git integration, with different pricing structures. All three offer a free option for limited server power. These are clearly great benefits, as it takes a lot of time investment to get your own server set up with more involved application architectures such as Rails or Node. Beyond that, scaling becomes very simple, as all three of these services offer load-balancing and scaling to multiple instances at the click of a button. These services take care of the hefty server administration for you, so you can focus on creating apps, knowing that there is a well-documented, safe, fast deployment strategy for you to use when you're ready to go public.

Conclusion

Hopefully, this article has removed some confusion about the differences between Git (and other VCSs) and FTP/SFTP, and what the concept of deployment means. Also, I hope that this has encouraged you to develop your own deployment strategy, with assistance from tools, like Git and Heroku. If you already have a strategy, what kinds of things do you do during deployment?