Like many people who deal with servers, I’ve been moving most of my sites to use Docker containers for software deployment. It makes structuring my applications as 12-factor apps much more straightforward, and it makes a microservices architecture easier to deploy and maintain.
So when I needed to set up a new blog for fuzzy.io, it made sense to use Docker for the WordPress install. This turned out to be easy, but it took a while to figure out how easy it is.
On the plus side, there are high-quality official images for both wordpress and mysql in the main Docker repository. Unfortunately, there are a lot of one-off images from questionable sources also in the main repo, which can make finding and using the official images a lot harder.
Adding to the confusion is the absolutely ridiculous Getting started with WordPress article for fig, which shows how to set up WordPress from scratch.
So, here is my simple recipe for running WordPress from within Docker.
1. Set up a Docker-enabled host
You need to be able to SSH into your server and run the docker command as root.
2. Set up a host name
However you set up domain names, this is probably a good time to do it. Make it point to the host you just set up.
I use Digital Ocean for DNS management, so it’s pretty easy to map the IP address for the host I just created to a new name.
3. Install fig
fig is a Docker orchestration tool. It makes it easy to set up, configure, and link multiple containers on a single host.
The install process is simple. As root on your server, run this command:
curl -L https://github.com/docker/fig/releases/download/1.0.1/fig-`uname -s`-`uname -m` > /usr/local/bin/fig; chmod +x /usr/local/bin/fig
Note that this doesn’t use the curl-to-shell anti-pattern; it just downloads the file to your /usr/local/bin directory and chmod’s it to be executable.
4. Write fig.yml
db: image: mysql:5.5 environment: MYSQL_ROOT_PASSWORD: "good password here" web: image: wordpress:latest ports: - "80:80" links: - db:mysql
Let’s break this down: first, it makes a container named “db” using the official mysql image for MySQL server 5.5. I tried using later versions of MySQL, like mysql:latest, but they blew up pretty badly when I tried them. Backing off to the latest 5.5 seems to work the best.
The environment variable MYSQL_ROOT_PASSWORD will be the root password for the MySQL server inside the container. You should make it a good password. It will be used automatically by the WordPress container.
Next, it makes a container named “web” using the latest official WordPress image. It maps port 80, the default HTTP port, from the host to the WordPress container. Finally, it links to the “db” container as its backend storage.
Save the fig.yml file in your /root/ directory.
5. Run fig
To start the containers, you run fig from the command line like this:
fig up -d
This will do a few things:
- It will pull the ‘mysql’ and ‘wordpress’ images from the Docker repository. This will take a little while, but only has to be done the first time.
- It will set up new containers for the ‘db’ and ‘web’ patterns you defined in your fig.yml. It will use a prefix equal to the name of the current directory, and a suffix for the ordinality of the container. So I get two containers, ‘root_db_1’ and ‘root_web_1’. Your mileage may vary.
Once this is done, you should be able to navigate to the hostname you set up in step 2 in your browser and see the WordPress site.
6. Do the WordPress setup
From the browser, you can now do the notoriously easy 5-minute WordPress setup.
That’s it! There are some nice things about the WordPress official image; it does a nice job dealing with permalink changes and other configuration items.
So, what do you think? Any suggestions for tightening up this process? Ways to make it easier or more secure? Let me know with a comment.