Over the years, I have been getting obsessed with Deployment systems, especially for Drupal/Laravel sites which is what I mostly work with.
Drupal 8 is using composer now to pull the code from core and contrib modules making it easier the process of sending deployments to different environments.
However, all the deployment systems I was using were custom bash code built by myself or my colleagues and I wanted something that it was built in PHP, after all, these deployment processes will be moving code for PHP frameworks like Drupal 8 and Laravel. Therefore, I just wanted to be consistent with just one programing language.
Deployment automation has never been easier
Before we start, here are a few concepts you need to visit first:
- Drupal composer template: https://github.com/drupal-composer/drupal-project
- Atomic Deployments: https://buddy.works/blog/introducing-atomic-deployments
Deployer (https://deployer.org) is an atomic deployment tool built in PHP which supports deployments workflows for popular frameworks out of the box.
Deployer uses recipes to help you out with most of the boilerplate for the most popular frameworks out there.
We will be using Drupal 8 to show how to implement it.
Installation
This will install deployed in your local computer
curl -LO https://deployer.org/deployer.phar
mv deployer.phar /usr/local/bin/dep
chmod +x /usr/local/bin/dep
Getting Started
With the installation above, you should be able to run the "dep" command.
You could do something like:
dep init -t Drupal8
and create the basic boilerplate on your deploy.php file.
Setting up the deploy.php file
All the Deployer's logic will live in a file called deploy.php, I like to place it in my repository root so I can run Deployer commands directly from the root of my project.
Let's see the content of the deploy.php file
<?php
namespace Deployer;
require 'recipe/drupal8.php';
// You should add server folder where your application lives.
set('application', 'PATH TO YOUR SERVER FOLDER');
// Add the Git URL from your Project
// TIP: the destination server should have access to clone the repo
set('repository', 'GIT URL');
// Set up the Share files or Directory
// In this case, we are using the Drupal 8 recepie. Therefore, Deployer will add the Drupal Files folder as a default share folder.
add('shared_files', []);
add('shared_dirs', []);
// MAX releases you want o keep on your server
set('keep_releases', 3);
// Hosts
host('IP ADDRESS DESTINATION SERVER')
->user('USER')
->port(22)
->identityFile('~/.ssh/id_rsa')
->set('deploy_path', '/{{application}}');
Defining tasks
Tasks are one of my Deployer's favourite features. With tasks, you can define instructions after or before one of the built-in Deployer tasks runs.
Here is an example: Before my deployment finish I need to make sure the new files are using the www-data user and group.
// Setting up a custom task called permissions:www-data
task('permissions:www-data', function () {
run('chown -R www-data.www-data {{application}}');
});
// Then at the end of my deploy.php file we add:
before('deploy:symlink', 'permissions:www-data');
I added a couple more tasks as an example, so here is my final deploy.php file:
<?php
namespace Deployer;
require 'recipe/drupal8.php';
// You should add server folder where your application lives.
set('application', 'PATH TO YOUR SERVER FOLDER');
// Add the Git URL from your Project
// TIP: the destination server should have access to clone the repo
set('repository', 'GIT URL');
// Set up the Share files or Directory
// In this case, we are using the Drupal 8 recepie. Therefore, Deployer will add the Drupal Files folder as a default share folder.
add('shared_files', []);
add('shared_dirs', []);
// MAX releases you want o keep on your server
set('keep_releases', 3);
// Hosts
host('IP ADDRESS DESTINATION SERVER')
->user('USER')
->port(22)
->identityFile('~/.ssh/id_rsa')
->set('deploy_path', '/{{application}}');
task('permissions:www-data', function () {
run('chown -R www-data.www-data {{application}}');
});
task('permissions:www-data:current-folder', function () {
run('chown -R www-data.www-data {{application}}/current');
});
before('deploy:symlink', 'permissions:www-data');
after('deploy:symlink', 'permissions:www-data:current-folder');
Well, I guess I have covered the basics here :)
Here is the docs in case you need more info: https://deployer.org/docs/getting-started.html
Top comments (1)
Is there any particular reason why you are running
chown
twice before and after the symlink?