I am going to tell you about the different steps you can take to make your website deployment process easier for yourself and smoother for your client and the server.
Website deployment can be as simple as FTP-ing files to the server—which is why most developers never really get too deep into it. Just uploading the files works for tiny sites and sites where downtime does not matter, but a truly efficient deployment is one that will provide uniterrupted service to visitors.
A seamless deployment involves the practice of release engineering, something that I think all developers will need to learn at some point. Release engineering is a bridge between development and quality assurance.
The Ultimate Goal
The highest form of release engineering is a complete continuous integration setup. Continuous integration means that when a new feature or commit is made, there is an attempt to integrate the new feature into a fully functional website package. Someone can then get a copy of any working package from the continuous integration system. This complete setup involves:
- automated builds with version control integration,
- a complete automated testing stack, and
- automated deployment to servers
Continuous integration may be overkill depending on the size of the project, but the addition of any of its subcomponents to a project would be immensely useful. The easiest of the three subcomponents to setup would be automated deployment, followed by automated builds, and finally automated testing.
Following continuous integration is continuous deployment, which means triggering an automated deployment of a functional package on every successful continuous integration iteration. This isn’t always helpful since websites updates might be made for a specific time (e.g., a New Year’s or Christmas design) and you don’t want to deploy that immediately.
Part 1: Automated Deployment
Setting up automated deployment is totally worth it whether you’re on one server or have multiple servers. “Automated” in this sense means you don’t have to do anything beyond issuing the initial “deploy” command, which could be clicking a button or typing in the command.
A proper automated deployment system should be capable of cleaning up the server to which it is deploying, like cleaning empty folders and files that are not in the build that is being deployed. Traditionally this is called a “clean” operation.
One method of performing an automated deployment is to give the target server access to your version control repository in some way. You can issue a pull/checkout on a clean server, and then update existing checkouts. Branches and tags can be used to make sure that the appropriate build is deployed. Pitfalls of this method are that the version control files will also be on the webserver (e.g., the .svn or .hg or .git folder).
Another method is to use a directory comparison tool, like Araxis Merge or Beyond Compare to do a folder synchronization.
An even more robust way to do this is to use a folder synchronization daemon like rsync or unison to watch a directory for changes. Rsync can even integrate with SCMs.
Daemons can be improvised using a system scheduler (cron, Windows Task Scheduler) and a scripted the deployment using shell scripts or batch files and robocopy/xcopy.
Finally, there are existing tools which are designed to do all of this for you. The tools are typically language dependent, like Capistrano for Ruby developers, and fabric for Python (Ruby developers shouldn’t have any problems using this, too, though). Puppet is another solution; and like the ones I’ve listed and many others, it crosses the line between automated deployment and automated build tools (which is my segué into the next section!)
Coming soon…
Part 2: Automated Builds
Part 3: Automated Testing
Part 4: Continuous Integration & Beyond