Using Envoyer for Deployment

June 13, 2016

The Problem:

For every deploy that was done to Kickfurther all user sessions would be destroyed. That means every-time one line of copy needed to be changed all users would be kicked out and forced to login again. If a company was in the middle of filling out their Co-Op information and uploading images and getting everything just right, sorry! Please login and do it all over again.

The Solution:

Laravel’s Envoyer, a Zero Downtime Deployment Solution. It allows us to deploy to production 50+ times a day if we need to. (Hopefully we don’t ever need to.)

Envoyer works by checking out your project into a releases folder which is named as a timestamp of when it was checked out, eg.


once all the deployment scripts have run, this release folder is then symlinked to


which is where the web root is pointed, so /var/www/ is always the most current codebase and nginx or other configurations never need to change.

The First Step:

The first step in hooking envoyer up is to give it the github repo of your project and tell it which branch it should be defaulting to. In Kickfurther’s case we have master, stage and dev projects to deploy the respective branches.

An individual branch can be chosen to be deployed in the situation that we want to deploy master to to do any final testing on the master branch.

Deployment Hooks:

The next step is to input your custom deployment hooks. In Kickfurther’s case we have separate Job and Web Servers which gives us a separation of concerns but that means they do not need the same deployment scripts. For example, the Job server does not need to run any npm tasks.

The deployment scripts can be completely customized based on your projects needs. In our case we are using supervisor to manage the queue workers and this needs to be restarted upon every deploy so it updates the symlink with the /current directory, thus always running the current release.

This screenshot shows how we are only running the npm install tasks on the Web Servers

This is an example of the deployment script I’ve setup to run npm install only when the package.json file has changed, otherwise there is no need to replace the node_modules folder and thus we would only run gulp –production since only the source files have changed.

cd {{release}}

# Compare the current package.json with the new package.json
# only npm install if they are different
if ! cmp -s {{project}}/current/package.json {{release}}/package.json
    rm -rf {{project}}/node_modules
    rm -rf {{project}}/bower_components

    npm install

    mv {{release}}/node_modules {{project}}/node_modules
    mv {{release}}/bower_components {{project}}/bower_components
# Compare the current bower.json with the new bower.json
# only bower update if they are different
elif  ! cmp -s {{project}}/current/bower.json {{release}}/bower.json
    rm -rf {{project}}/bower_components

    npm run bower

    mv {{release}}/bower_components {{project}}/bower_components

ln -s {{project}}/node_modules {{release}}/node_modules
ln -s {{project}}/bower_components {{release}}/bower_components

npm run gulp

A Deployment:

A deployment from start to finish


Envoyer has given us the peace of mind that our deploys will always follow a repeatable pattern with insight into all output done on each command.

It has taken a once complicated task and reduced it down to a push of a button.

Isn’t that what all SAAS should strive for?