Deployment as it should be

Most web developers have a lot of focus for writing quality applications. They ensure their markup and style is displaying correctly in multiple browsers, and they focus on their code, some even write unit tests and functional tests ;)

Additional measures are having seperate development, test, staging and production servers. Having seperate test teams. Have client tests. But all this focusses on the workings and looks of the application.

I've worked for quite a few companies, and I've seen some methods of deploying. The worst was using ftp for deploying an application. Usually this resulted in errors as parts of the application were updated already and other parts weren't. And especially with bigger applications, this causes problems for a longer period of time.

Slightly less bad was deploying from version control (CVS or svn). Usually we'd make an export in a temporary place and then simply move the files to the correct position. This works pretty OK I must say, but when moving away the old version (backup!) uploaded files were also gone and so this required quite a lot of work.

One of the options of symfony's commandline interface is the ability to deploy applications to servers using the symfony sync command. In a configuration file, you can define a list of servers that you want to deploy to. Each server has a snippet in there similar to this:


As you see, this is basically all information you need to deploy an application, aside of course from the password which you wouldn't want to specify in a configuration file if it isn't required. Instead, as soon as you issue the symfony sync command for this server, it will ask you for your password. There are, in the case of the above server, two commands you can issue:

symfony sync production
This will do a dry run, to see if the deployment of the files might cause a problem

symfony sync production go
This will actually send the files over to the specified server.

Now, because the symfony sync command uses rsync, only those files that have changed are deployed to the specified server. Aside from the first deployment, in which case all files need to be sent to the server, this speeds up deployment big time as only a selection of files are transferred.

Aside from easily transferring the necessarily files, symfony also makes sure that the files you don't want to have deployed won't. For this, there is the rsync_exclude.txt file. In this file is a simple list of files (which can include wildcards, so you can exclude whole directories or files with a certain naming convention) that should not be deployed. Good examples of files you'll want listed in this file are the _dev.php development environments, your databases.yml (to ensure you don't overwrite your database configuration with an incorrect one) and your cache and log directories (listed by default).

Now we have transferring files covered. But database changes also need to happen as you deploy of course, because your new code will depend on those. In symfony 1.0, I personally always use batch job which can be called from the commandline. In symfony 1.1 it will be even easier, as the recommended way to do it then is to use actual symfony tasks (which can easily be written, in 1.0 already by the way).

So, in short, deployment will then be:

  • deploy code using symfony sync
  • call the batch job/symfony task to update the database and possibly do other required stuff
  • symfony cc (clear cache) - though this could be done from the above batch job/symfony task as well

And what is left is testing if everything went well.

Of course, having a powerful tool such as this at your fingertips does still require you to keep your head clear and keep thinking about what you are doing, but it definitely makes it much easier and ensures you don't have to think about everything.