PHP deployment using SVN and Git

Traditionally we use Subversion in LeaseWeb. Recently we started to move to Git. This is not an easy move; It requires education, integration and backwards compatibility tricks to make sure productivity is not impacted. Now that the most problems are solved we are beginning to see the advantages and opportunities that Git offers us. One of the nice things has to do with the deployment flow.

If you use SVN you could do “svn up” on the production server. This is a very simple way of deploying that works if you follow two important rules: 1) do not commit config files and 2) do not change any non-config files on production. When you follow these rules you know that you will not run into merge conflicts during deployment.

Another approach is to create a deployment script that deploys and configures into a seperate directory and then changes the target location of the symlink that is configures as the document root for the webserver. This allows you to keep directories with version numbers and do easy rollback (assuming the database is not impacted). The actual symlink change is atomic (according to Mike Zupan) and I believe he is right.

The first approaches requires SVN access from the production server. In the second approach the code could be checked out using “svn export” and then packaged using “tar -cvzf” and copied over using “scp” and then unpacked and as a last step the symlink can be switched (make sure you set the right permissions). Obviously one can easily write a small bash script that automates all this.

With Git we have another very stylish option: “git push production”. We can setup a second remote called “production”. The first remote is called “origin” and this is the location where you downloaded the repository from, hence the name. With the command “git remote add” you can add the production server. You must create a bare repository on the production server to push to. The push operation to the production server uses SSH to connect and transfer the files. Logging in can be secured and automated using key-based authentication just like with “scp”.

After the push you can tell Git to automatically deploy using a “post-receive” hook. With Git you can also choose for either a “svn up” like solution using “git pull”, or a symlink flip after issuing a “git clone” and configuring the project. Don’t forget to remove access to the hidden “.git” directory in your project. Accidentally serving it is probably not a smart idea.