Easier Drupal Development with Docker

In one of my previous post, I discussed about how I moved away from Drupal and started using Ghost for my blog. Drupal was like a big gun for a small job in that case. But still, as a content management framework for quickly prototyping complex projects, Drupal is still my first choice.

The last time I used Drupal in a production project was when Drupal 7 was the latest version. A lot has changed since then, Drupal has a brand new version: Drupal 8 and I didn't have chance to check it out.

Recently I had an idea about a project that I wanted to prototype. Among all the option in hand, Drupal was one of the best choices for that project. I wanted to start as fast as possible without working too much on configuration. I also wanted to share the development among my three development Mac 😎

I started by downloading Drupal 8.5 in my computer, unpacked the archive, then deleted everything except for the modules, profiles, sites, themes folder. created a folder named data for mysql And added a docker-compose.yml file. The whole folder structure looked like this:

data/
docker-compose.yml
modules/
profiles/
sites/
themes/

In drupal 7, only the sites folder needed to be stored as persistent, but for drupal 8, they changed the folder structure, the theme, module, profiles and sites folder needs to be persistent now. The data folder will be used by mysql to persist data.

As my computer had Docker and Docker-compose already installed, it was only a matter of writing the compose file for the project, I tried to keep it as simple as possible. Here's the compose file I wrote:

version: "3"
services:
  drupalapp:
    image: drupal:8-apache
    volumes:
      - ./modules:/var/www/html/modules
      - ./profiles:/var/www/html/profiles
      - ./sites:/var/www/html/sites
      - ./themes:/var/www/html/themes
    ports:
      - 8090:80
    restart: always
  database:
    image: mysql:5.7
    volumes:
      - ./data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_DATABASE=drupal
      - MYSQL_USER=drupal
      - MYSQL_PASSWORD=supersecret
    restart: always

In this compose file, there are two service defined, One uses the drupal:8-apache base image this is from the Official Drupal Docker Image, the container will have four volumes (for the folders mentioned previously) and host port 8090 will be mapped to the container port 80

The database service is based on the official Mysql image, and has one volume to persist the database data. the mysql configuration was supplied using environment variables.

Once the compose file is complete, I ran the below command:

docker-compose up -d

The command pulled the images and did all the rest of the magic, then two services turned on successfully. I went to the web browser, navigate to localhost:8090, and was greeted with the Drupal installer page.

In the database configuration page of the the Installer,  I set in the config set in the compose file. For the database server in the advanced section, the database service name in compose (in this case database) is used. It looked something like this:

Database Configuration

Once the installation was done, I had a Drupal instance up and running. It's easy to share the installation too, the compose file with the folders can regenerate the whole thing with one simple compose command:

docker-compose up -d

And the changes made in the theme and plugins stay. Thanks to the volumes 🤞🏾

This might not be the best setup for Drupal out there, this is what I used, if you have better setup in mind, please let me know in the comments.