Joris Vercammen

Deploying drupal 8 with jenkins

Recently we’ve set up automated deployments for our new Drupal 8 projects at dazzle. We’ve set up a new server with a jenkins-instance, we added bitbucket integration so that a new push to origin/* triggers the jenkins server to make a new build.

We’re using a fork of drupal-composer for all of our projects, so they all have the same layout. They all have a root folder that looks like this:

web/
vendor/
scripts/
 - build.sh
 - deploy-qa.sh
 - deploy-prod.sh
composer.json
composer.lock

Our build-script is probably the easiest out of all scripts but it’s also the one that’s does the actual transforming from the codebase into a working website. We’ve set up jenkins so that it executes ./scripts/build.sh, which mean we can change the way projects are built to suit the project’s specific needs.

After the build-script has run, jenkins will execute deploy-qa or deploy-prod depending on the target environment. We’ve set it up with the scripts in the project repository so that we can keep our jenkins setup very simple; most of us know how to write things in bash, while we don’t have a lot of experience with the jenkins system and I figured it’d be easier to stick with what we know.

This is what the basic build-script looks like.

#!/usr/bin/env bash
# Install all dependencies.
composer install --dev;
# Build all theme dependencies and assets.
cd web/themes/custom/project_foundation;
npm install;
gulp bower;
gulp build;
cd -;

# run phpunit
./vendor/bin/phpunit -c web/core web/modules/custom

# install composer dependencies again without dev dependencies for smaller build
# result
composer install --no-dev;

You can see that we’re going into the project_foundation folder, this is a sub-theme of zurb_foundation, it’s not called project_foundation in our actual projects though, the install-script replaces project with the name of the actual project, so for a website “foo”, this’ll be foo_foundation.

We’re currently not running PHPCS on this to check for coding standards in our custom projects, but that’s on the todo-list, I was hoping to see https://www.drupal.org/node/2744463 land in 8.2, but it looks like that’ll be 8.3+ so we’re going to be integrating that ourselves in the coming weeks. Other things I’d like to figure out is running PHPMD with sane settings and running a PHP-linter.

Our deploy scripts both work in pretty much the same way, I won’t be pasting code here, but it’s pretty easy to figure out. First off, we’re bundling all the results into a tar-ball, then moving that file the other server trough scp. On the remote server, we’re unpacking the results into a site.new folder, then moving the current site folder to site.old before moving site.new into site. This means that we always have 2 checkouts of files in the server and we can switch back to the previous version really easy.

After that, we move into site; import configuration and clear caches. And just like that, the new version of the site is online.

Currently our builds take about 2 minutes to finish, with the bulk of the time spent on npm install / gulp build. That time doesn’t really matter though, we deploy 5-10 times a day, depending on how many people are working on a project and our customers can follow along with the progress on their sites in real-time.

Originally written for the dazzle.be blog