Thoughts on Deployer

Published: 4 years ago php web dev

I have started to use Deployer a task runner/deployment tool written in PHP for deploying my site in a single command.


The best way to use Deployer is to forward your SSH keys using the forwardAgent option. This way you don't have any private keys left on the server incase it gets compromised. You need to ensure you are forwarding both the key to access your server remotely and (if separate) the key to access GitHub remotely. To keep things simple, I just set up a new private key and used the same one for both:

Generate a new ssh key, add it to ssh-agent, add public key to Github and your server:

ssh-keygen -t rsa -b 4096 -C "email"
ssh-copy-id you@host
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

There is already a good guide on how to set this up on GitHub, and specifically for configurating forward agent, here.

Deployer still seems a little rough around the edges in a couple of instances:

The main problem I had was trying to install and run it via composer. It redefines set() which is a Laravel function and this causes then issues. The easiest solution is to download the deployer.phar and put it in /usr/local/bin instead. Apparently 4.x, currently in dev, actually uses namespaces so this should be fixed.

Unfortunately Deployer's documentation is not great. There is no real reference guide, there are just code samples scattered across vaugely grouped together help pages. The easiest way to get a feel for what's going on is to look at one of the recipies, for example the Laravel one.


I've done a couple of little tweaks. The Laravel receipe does not run migrations by default. This is configured as a separate task. However I'd prefer to always run migrations on deploy, if there are any. This is easy to do by adding this to the bottom of your deploy.php:

after('deploy', 'artisan:migrate');
after('rollback', 'artisan:migrate:rollback');

One other thing I've had to do is create a quick task to generate a symlink from storage/app to public/storage so that stored files are publically accessible. The new Laravel 5.3 release has an Artisan command to create this symlink but 5.2, which I'm currently using, does not. So here is the simple deployer task:

task('laravel:symlink', function(){
	run('ln -s ../storage/app current/public/storage');

You can then run this task separately after deploying - it should only need to be run once:

dep laravel:symlink production

Final thoughts

Generally Deployer is quite nice but I think it would only really pay off if you a) have to deploy to multiple servers concurrently b) have many stages of deployment (testing, staging, production etc.) c) have a regular need to quickly rollback broken releases. I think for a simple site such as this using Git would suffice.

Regardless I will continue to use Deployer so stay tuned for more blogs posts as there's a bunch of things still to try and work out:

  • The best way of using ssh agent to forward the ssh keys
  • Hooking pushes to master to automatically run Deployer