Local WordPress Development with Docker: 3 Easy Steps

Update: Be sure to check out the second part on using wp-cli with this Docker tutorial.

Update 10/23/2016: I have updated the snippets to use docker-compose version 2.

Docker is cool, but since I am a toolaholic I am not going to waste your or my time preaching about how you must use it. You are a human, after all, so you get to choose which tools you prefer.

My toolbelt for developing WordPress sites locally has changed over the years. First, I just used an Ubuntu machine with a LAMP stack that I installed via Tuxlite. Then I budgeted for a Mac and found MAMP, but once I became more comfortable in bash, a plain ol’ Ubuntu VirtualBox was what I preffered. Then Vagrant came along! Sadly, I was too noob and just ended up back with MAMP. That worked for a while and I just made sure I didn’t touch anything (I was using Nginx on MAMP so configuration was a little more tedious for me compared to my comfort zone with Apache).

When Docker came along, I quickly grabbed it by the reigns and tested the shit out of all kinds of use cases to the point where I even suggested to my boss that we use it in a few production scenarios. Only until recently, Docker development flat out sucked on Mac and Windows due to the numerous issues with sharing files between the machine and the containers (so I just installed Ubuntu 16.04). On top of that, in Mac & Windows, you had to install Docker inside a Virtualbox via docker-machine. Now, it is nearly-native for each platform and many of the kinks have been worked out. Anyway… that is my schtick on why I feel comfortable using it now for local development. Let’s get to the toot!

The Quick and Dirty

If you just want something to copy and paste and go, I’ll just cut the crap and give it to you.

https://gist.github.com/tatemz/504383c921aa5898c49b82d4ee181362#file-docker-wordpress-sh

Let’s go into detail… but first, make sure you have Docker installed.

https://www.docker.com/products/docker

1 - Setup docker-compose

Before I go on, I need to say something. You can copy and paste these snippets all day and they will work for you. You can use what I know from trial and error to get something up and working without the sweat, but until you actually go and read the documentation on docker or docker-compose you probably will not be able to customize and hack together your own process. That said, here we go.

Navigate to your WordPress project folder. If you don’t have WordPress downloaded yet, that is okay. The official WordPress container will clone it for you.

Create a file named docker-compose.yml

$ mkdir wordpress-site && cd wordpress-site
$ touch docker-compose.yml

2 - Create Your Containers

WordPress needs a LAMP stack to run. In this process, we are splitting that LAMP stack into two containers: one that runs the database (MySQL or MariaDB), and one that runs the webserver (PHP with Apache or PHP with Nginx).

Paste the YAML configuration for your database container that we are naming “my-wpdb”

my-wpdb:
image: mariadb
ports:
- "8081:3306"
environment:
MYSQL_ROOT_PASSWORD: ChangeMeIfYouWant

Here we are using the offical mariadb image, mapping our local port 8081 to the container’s port 3306, and giving it an environment variable containing the root user’s password. “MYSQL_ROOT_PASSWORD” is picked up by a shell script that runs when the container boots; it will install users with passwords and do some more magic.

Now we have a database container, but we still need PHP and Apache (and WordPress files).

Paste the YAML configuration for your WordPress container that we are naming “my-wp”

my-wp:
image: wordpress
volumes:
- ./:/var/www/html
ports:
- "8080:80"
links:
- my-wpdb:mysql
environment:
WORDPRESS_DB_PASSWORD: root

We are still using official Docker images at this point and this one is the official WordPress image. It’s also has a shell script that automatically connects to the database container we created earlier, creates a database, clones WordPress files, and sets up the wp-config based on environment variables that we pass to it (see the official image page for all the options).

Just like the database container, we are mapping our machine port 8080 to the container port 80. Additionally, we are mounting our current directory ./ to the container’s webroot directory /var/www/html. Docker calls these “volumes”. This allows your project to live on your local machine and be shared to the container.

Notice that we are linking our my-wpdb container onto our my-wp container. More specifically, we are telling my-wp that it will refer to the my-wpdb container with an alias named “mysql”. This is because the shell script in the WordPress container has hardcoded the database hostname as “mysql”. Docker is just magically assigning a hostname to the my-wpdb IP address.

Whew!

3 - Run and Connect

Now you can create your containers and run them, and docker-compose makes this extremely easy!

$ docker-compose up -d

You can now browse to http://localhost:8080/ and see your WordPress installation dialog! If you want to connect to mysql, just be sure to use the address 127.0.0.1 and the port 8081 like we mapped above. The hostnames and IP addresses may differ depending on how you have installed Docker, but these will work if you use the distributed Docker installations.

If you want to see the output of the containers (to monitor for errors), follow their logs:

$ docker-compose logs -f

If you ever want to stop and restart your containers just run

$ docker-compose stop
$ docker-compose up -d

Ask me questions via comments or on Twitter https://twitter.com/tatemz!