Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

 

Making deployment a piece of cake with Deployer

Here's the tool that makes the process of deploying a SilverStripe site very easy and customisable.

Read post

Introduction

Ah, the good old days of the web. I remember a time when all that was required to launch a website was to write some HTML in a text editor and FTP it to a server. Today, even relatively simple websites have become applications for the most part, and are a much different beast altogether.

Modern web applications typically consist of source code, file assets, innumerable dependencies, package management... the list goes on and on. As developers, we are constantly looking for tools to help automate as much of the web application building process as possible. But what about deploying your project to a server?

If you're still using FTP to upload sites to live servers these days, then you're a courageous soul indeed. If you're not using a deployment tool, now would be a great time to start. But where to begin? You're pressed for time already—you don't have weeks to spare learning all the nuances of Phing or Capistrano!

Enter Deployer!

What is Deployer?

Deployer is a simple deployment tool for PHP. If you've ever used Composer to manage your project dependencies (and let's face it, if you've developed anything with SilverStripe over the last few years, you've probably used Composer), you'll feel right at home with Deployer.

By installing Deployer and setting up some simple configuration, you can quickly and easily deploy your SilverStripe applications to either staging or production environments with typically only one short command.

Getting Started

Like Composer, Deployer is packaged as a PHAR file that is downloaded to your local machine. Once you have it downloaded, you'll need to copy the PHAR to your preferred location for executable commands, e.g. /usr/local/bin. Alternatively, you can install it globally via Composer:

$ composer global require deployer/deployer

Once installed, the 'dep' command will become available for use. I actually prefer to rename mine to 'deployer', but I will continue to use 'dep' in this article for consistency with the official documentation.

Using Deployer

Deployer uses a regular PHP file for its configuration and deployment tasks. By convention, this is called 'deploy.php' and typically sits in the root of your project. You can create a stub configuration file by running $ dep init

The deploy.php file makes use of a number of 'recipes' for different platforms. Version 4.0 of Deployer includes a SilverStripe recipe out of the box. However, if you'd prefer to write your own, you can require the 'common' recipe in your deploy.php for a head start:

require_once "recipe/common.php";

Your deployment procedure will typically consist of one or more tasks. Deployer makes it really easy to define your own tasks within deploy.php, for example:

task('helloworld', function () {
   writeln('Hello world!');
})->desc('Says hello to the world!');

The task 'helloworld' will now be available via the dep command when run in your project root:

$ dep helloworld
➤ Executing task helloworld
Hello world!
✔ Ok

It's that easy! However, saying 'hello world' won't help deploy your app. Let's look at how to deploy a SilverStripe project using Deployer.

Setting up Servers

You can define your application servers in two ways: either by using the 'server' function within your deploy.php file, or by using a YAML file. Here's an example of the server function:

server('staging', 'myapp-staging.example.com')
   ->user('www')
   ->set('deploy_path', '/home/myapp-staging')
   ->stage('staging')
   ->identityFile();

Alternatively, you can use a YAML file to define your servers:

production:
 host: myapp.example.com
 user: www
 identity_file: ~
 stage: production
 deploy_path: /home/myapp/

You can load the YAML server configuration in your deploy.php file by using serverList('servers.yml');

There are a number of ways to handle SSH authentication in order for Deployer to connect to your server. Using the identity file method above will authenticate using your user id_rsa.pub file, and allows you to commit your deploy.php to VCS without storing sensitive username and password data. Be sure to add your id_rsa.pub to the list of authorised keys on the server!

Defining your Repository

Deployer needs to know where it can clone your project's code from. You can do this by using the set function to define a configuration parameter called 'repository':

set('repository', 'git@domain.com:username/repository.git');

You can configure the branch of the repository to checkout by supplying a 'branch' option in your server configuration. You could use the master branch for production, and a develop branch for staging, for example.

Deployer can also access private repositories on both GitHub and Bitbucket (for example, if you're deploying a project for a client with closed-source code). Make sure you set up the relevant SSH keys in your repository control panel so that Deployer can access your private repos!

The Deploy Task

The real meat of your deploy.php file is the aptly named ‘deploy’ task. Let's examine the task from the SilverStripe recipe that ships with Deployer:

task('deploy', [
   'deploy:prepare',
   'deploy:lock',
   'deploy:release',
   'deploy:update_code',
   'deploy:vendors',
   'deploy:shared',
   'deploy:writable',
   'silverstripe:buildflush',
   'deploy:symlink',
   'deploy:unlock',
   'cleanup',
])->desc('Deploy your project');

As you can see, a task can be composed from any number of subtasks. Most of the tasks listed above come from the common.php recipe, and are responsible for preparing the server for your project. Deployer takes care of cloning your project repo, installing your dependencies (via composer install and your composer.lock file), and also setting up shared and writable folders (e.g. assets).

The SilverStripe recipe includes two additional helper tasks:

task('silverstripe:build', function () {
   return run('{{bin/php}} {{release_path}}/framework/cli-script.php /dev/build');
})->desc('Run /dev/build');
task('silverstripe:buildflush', function () {
   return run('{{bin/php}} {{release_path}}/framework/cli-script.php /dev/build flush=all');
})->desc('Run /dev/build?flush=all');

These tasks can be integrated into your main deploy task to automatically perform either a dev/build, or a dev/build and flush on your SilverStripe project after a successful deployment.

Performing the Deployment

Your project is built within its own folder, with Deployer creating a symlink that points to your current release. This allows for atomic deployments with zero downtime, as the symlink will instantly change from the previous to the current release after the deployment is complete.

When you've pushed your latest changes to your repo, you're ready to deploy to a staging server you have configured. It's as simple as running $ dep deploy staging

Deployer will execute your deploy task, just as you have defined it in your deploy.php file. If you'd like to set a default stage to deploy to, without having to type it each time, you can define the 'default_stage' parameter in your configuration file: set('default_stage', 'staging');

That way, you can deploy to your default stage simply by running $ dep deploy

If something goes wrong, you can always roll back to your previous release by running $ dep rollback

A rollback will delete the current release folder and restore the symlink to the previous release. Your rollback task can also be customised if desired to include additional functionality, such as database rollbacks.

Conclusion

This article has only covered the basics of using Deployer to automate your SilverStripe app deployments. There are many more options and functions available to handle pretty much anything you can think of! Check out the official documentation to learn more.

If you haven't used a deployment tool before, I really encourage you to give Deployer a try. Its simple API makes the process of deploying a SilverStripe site very easy and customisable.

About the author
Colin Tucker

Colin Tucker is a freelance developer at Praxis Interactive, located in Canberra, Australia, and specialises in solutions for small business, government, and non-profit organisations.

Post your comment

Comments

  • Hi Colin, this sounds great BUT... I used composer to download Deployer to my User Directory. I then tried to run '$ dep init' to be told 'command not found'. Obviously my system hasn't read the same manuals as yours. Or I've installed Deployer in the wrong place? Any insights? (BTW I'm still not overly comfortable about this command line stuff)....

    Posted by mike, 10/09/2018 4:32pm (6 years ago)

  • I find using Envoyer instead of Deployer quite easy because it gives you a UI. No need to use any command line for deploying from git repo (here is an example: https://www.cloudways.com/blog/php-laravel-envoyer-deployment/ ). Even though Envoyer is Laravel product, it can be used with any PHP app regardless of the CMS or framework it is using. So, why someone would use Deployer or Deploybot>

    Posted by olidev, 27/12/2017 9:40pm (6 years ago)

  • Love it. I usually use deploybot but this seems a worthwhile alternative.

    Posted by Franco Springveldt , 22/02/2017 1:31pm (7 years ago)

RSS feed for comments on this page | RSS feed for all comments