Over the last 2 or 3 years, the Drupal community has been converging around a solid set of Docker-based workflows to manage local development environments, and there are a number of worthy tools that make life easier.
My personal favourite is Lando, not only because of the Star Wars geekery, but also because it makes easy things easy and hard things possible (a lot like Drupal). I appreciate that a “standard” Lando config file is only a few lines long, but that it’s relatively easy to configure and customize a much more complex setup by simply adding the appropriate lines to the config.
In this post I want to focus on an additional tool I’ve come to lean on heavily that complements Lando quite nicely, and that ultimately boils down to good ol’ fashioned Makefiles. Last summer at DrupalNorth I gave a talk that was primarily about the benefits of Lando, and I only mentioned Drumkit in passing. Here I want to illustrate in more detail how and why this collection of Makefile tools is a valuable addition to my localdev toolbox.
The key benefits provided by adding a Drumkit environment are:
make <target>-based workflow to tie various dev tasks together
- ease onboarding of new devs (
- make multistep tasks easier (
- make tasks in Lando or CI environment the same (ie. make install && make tests)
Drumkit is not just for Drupal!
This example is using Drumkit for a Drupal 8 localdev environment, but there’s no reason you couldn’t use it for other purposes (and in fact, we at Consensus have lately been doing just that.
As an example, suppose you’re setting up a new D8 project from scratch. Following this slide from my Lando talk, you would do the basic Lando D8 project steps:
- Create codebase with Composer (
composer create-project drupal-composer/drupal-project:8.x-dev code --stability dev --no-interaction)
- Initialize Git repository (
- Initialize Lando (
For now, leave out the
lando start step, which we’ll let Drumkit handle momentarily. We should also customize the
.lando.yml a little with custom database credentials, which we’ll tell Drumkit about later. Append the following to your
services: database: creds: user: chewie_dbuser password: chewie_dbpass database: chewie_db
To insert Drumkit into this setup, we add it as a git submodule to our project
using the helper
script, and bootstrap Drumkit:
wget -O - https://gitlab.com/consensus.enterprises/drumkit/raw/master/scripts/install.sh | /bin/bash . d # Use 'source d' if you're not using Bash
The install script checks that you are in the root of a git repository, and
pulls in Drumkit as a submodule, then initializes a top-level
Finally, we initialize the Drumkit environment, by sourcing the
(itself a symlink to
.mk/drumkit) into our shell.
Drumkit modifies the (shell) environment!
Note that Drumkit will modify your
BIN_PATH variables to
add the project-specific
.mk/.local/bin directory, which is where Drumkit
installs any tools you request (eg. with
This means if you have multiple Drumkit-enabled projects on the go, you’re best
to work on them in separate shell instances, to keep these environment
Note that you can take advantage of this environment-specific setup to
customize the bootstrap script to (for example) inject project credentials for external
services into the shell environment. Typically we would achieve this by
scripts/bootstrap.sh that in turn calls the main
.mk/drumkit, and re-point the
d symlink there.
Set up your kit
Because we’re using Composer to manage our codebase, we also add a
COMPOSER_CACHE_DIR environment variable, using the standard
which Drumkit’s stock bootstrap script will pull into your environment:
echo "COMPOSER_CACHE_DIR=tmp/composer-cache/" >> .env . d # Bootstrap Drumkit again to have this take effect
From here, we can start customizing for Drupal-specific dev with Lando. First, we make a place in our repo for some Makefile snippets to be included:
mkdir -p scripts/makefiles echo "include scripts/makefiles/*.mk" >> Makefile
Now we can start creating
make targets for our project (click the links below to see the file contents in an example Chewie project. For modularity, we create a series of “snippet” makefiles to provide the targets mentioned above:
- scripts/makefiles/variables.mk sets up some project variables
- scripts/makefiles/lando.mk provides targets to start, stop, poweroff, and destroy the Lando containers
- scripts/makefiles/build.mk provides targets to build and update the codebase
- scripts/makefiles/install.mk provides targets to install the Drupal site
NB You’ll need to customize the
variables.mk file with the DB credentials
you set above in your
.lando.yml as well as your site name, admin user/password, install profile, etc.
Now our initial workflow to setup the project looks like this:
git clone --recursive <project-repo> cd <project-repo> . d # or "source d" if you're not using Bash make start make build make install
This will get a new developer up and running quickly, and can be customized to add whatever project-specific steps are needed along the way.
But wait- it gets even better! If I want to make things really easy on fellow
developers (or even just myself), I can consolidate common steps into a single
target within the top-level Makefile. For example, append the
target to your
.PHONY: all all: @$(MAKE-QUIET) start @$(MAKE-QUIET) build @$(MAKE-QUIET) install
Now, the above workflow for a developer getting bootstrapped into the project simplifies down to this:
git clone --recursive <project-repo> cd <project-repo> . d make all
Customize your kit
At this point, you can start adding your own project-specific targets to make
common workflow tasks easier. For example, on a recent migration project I was
working on, we had a custom Features module (
ingredients) that needed to be
enabled, and a corresponding migration module (
needed to be enabled before migrations could run.
I created the following make targets to facilitate that workflow:
- scripts/makefiles/migrate.mk provides
We often take this further, adding a
make tests target to setup and run our
test suite, for example. This in turn allows us to automate the
build/install/test process within our CI environment, which can call exactly
the same make targets as we do locally.
Ultimately, Drumkit is a very simple idea: superimpose a modular Makefile-driven system on top of Lando to provide some syntactic sugar that eases developer workflow, makes consistent targets that CI can use, and consolidates multi-step tasks into a single command.
There’s lots more that Drumkit can do, and plenty of ideas we have yet to implement, so if you like this idea, feel free to jump in and contribute!
We've disabled blog comments to prevent spam, but if you have questions or comments about this post, get in touch!