back home

Site, data & file systems. Starting to compose the WordPress Docker environment

Written by Bunkers on February 26, 2017

This is the third post in my series on creating a WordPress development environment with Docker. If you haven't read the other two they start here with the introduction, and the second is yesterday's post on setting up the database container.

Today I'm going to start covering the data container. The potential confusion with the database makes it badly named. In fact it's only called data in my docker-compose file so you may want to change it!

Start by creating another sub-directory alongside your percona directory, called site (a candidate if you want to change the name in the docker-compose file later). We'll begin with the Dockerfile. Create it in the site directory and give it the following contents:

FROM debian:wheezy
 
RUN set -ex; \
    \
    apt-get update; \
    apt-get install -y \
        curl \
    ; \
    rm -rf /var/lib/apt/lists/*;

I've taken a large quantity of this file from the official WordPress Dockerfile, which I encourage you to look at. This sets our base image as Debian, before installing updates and curl which we'll use to grab the latest versions of the software we need.

Continue by adding the following to your Dockerfile:

ENV WORDPRESS_VERSION 4.7.2
ENV WORDPRESS_SHA1 7b687f1af589c337124e6247229af209ec1d52c3
 
RUN set -ex; \
    curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \
    echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
    tar -xzf wordpress.tar.gz -C /usr/src/; \
    rm wordpress.tar.gz; \
    chown -R www-data:www-data /usr/src/wordpress ; \
        curl -o searchreplace.tar.gz -fSL "https://github.com/interconnectit/Search-Replace-DB/archive/master.tar.gz"; \
        tar -xzf searchreplace.tar.gz -C /usr/src/;

This downloads and extracts the latest WordPress source, as well as InterconnectIT's tool for running a search and replace on the database. In my development environment, I often find I'm transferring a copy of the database from production. I use this tool to replace the domain names. To make it simpler I've created a helper script which I'm going to make available in this container.

There's two scripts we need to develop. The first is entrypoint.sh which is the startup script for the container, and the other is dbsearchreplace.sh which is the helper script to convert the domain names in the database. Add the following to your Dockerfile

COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
 
COPY dbsearchreplace.sh /usr/src/Search-Replace-DB-master
RUN chmod +x /usr/src/Search-Replace-DB-master/dbsearchreplace.sh
 
WORKDIR /var/www/html
 
VOLUME /var/www/html/wp-content
 
ENTRYPOINT ["entrypoint.sh"]

This copies our two (yet to exist) scripts in to the appropriate locations and makes them executable. It then sets up the working directory and a volume so we can mount a directory for our WordPress content on the local drive. Finally, it sets our entry point script which, by default, runs as the container starts.

To get us up and running create an entrypoint.sh file with the following:

#!/bin/bash
set -euo pipefail

We're going to come back to this in more detail later. Then create dbsearchreplace.sh which looks like this:

#!/bin/bash
cd /var/www/html/Search-Replace-DB-master
php srdb.cli.php -h $WORDPRESS_DB_HOST -n $MYSQL_DATABASE -u $MYSQL_USER -p $MYSQL_PASSWORD -s $1 -r $2 $3

This runs the command line version of the search and replace tool, and sets up the database connectivity from our environment variables. We'll be creating another script that relies on this later.

Now we can create out docker-compose.yml file. As we've got two containers, it's time to start using docker-compose to manage them.

In our project directory (the parent to percona and site) create a docker-compose.yml configuration file:

version: '2'
services:
  percona:
    build: ./percona
    container_name: percona
    ports:
      - "3306"
    env_file: ./db.env
  data:
    build: ./site
    env_file:
      - ./db.env
    volumes:
      - /var/www/html
      - ./wp-content:/var/www/html/wp-content

Even if you haven't come across these files before, it's hopefully understandable. A service is a container and we're defining two. The first is the Percona container we built yesterday and the second is the data container we're currently working on. They both reference the same db.env file which allows them to have access to the database environment variables. The other important thing is the last line which mounts our local wp-content directory in the right place in the container. Create this directory now, and we can test bringing the two containers up with:

docker-compose up -d

This will build the containers and run them. Our data container will exit, but that's OK as it's just going to supply volumes to our other containers.

That's a lot to adsorb, so I'll leave it there for today. The entry point script is complex and we also need to setup our web server and PHP containers. Phew, coffee time again!