29 Jul

Containerising your Word Press blog with Docker

In this post, I will talk you through how you can create a copy of your live Word Press blog as a Docker container. The reason I wanted to do this, is so that I can test actual updates and themes to my live site before making them publicly available and seeing how any tested plug-ins interact with actual live content.

The first thing you need to do is make sure you have Docker installed or have access to a Docker host.

Pull down the Word Press, MySQL and PhpMyAdmin prebuilt Docker images from the Docker hub

docker pull wordpress
docker pull mysql
docker pull phpmyadmin/phpmyadmin

Just to note at the time of writing this post the tags for each where:

Image Tag Dockerfile
wordpress 4.5 https://github.com/docker-library/wordpress/blob/6afa0720da89f31d6c61fd38bb0d6de6e9a14a49/apache/Dockerfile
mysql 5.7.13 https://github.com/docker-library/mysql/blob/f7a67d7634a68d319988ad6f99729bfeaa84ceb2/5.7/Dockerfile
phpmyadmin/phpmyadmin 4.6.3-1 (from GitHub tag) https://github.com/phpmyadmin/docker/blob/4.6.3-1/Dockerfile

We now need to download a snapshot of your current live word press blog. This is very hosting company specific but in the lowest generic terms possible you need to download all files that come under the www root directory on your hosting companies servers and to export a copy of your Word Press MySQL database. In the rest of this post I will refer to the copy of the www root directory as the Word Press files and I will refer to the export of the MySQL database as the database.

At this point we need to run up a MySQL and PhpMyAdmin container. Execute the following on the Docker host.

docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pwd -d mysql
docker run --name phpmyadmin -d --link wp-mysql:db -p 8081:80 phpmyadmin/phpmyadmin

A MySQL server instance will now be running on the Docker host and it can be administered from the PhpMyAdmin instance running on port 8081 of the Docker host.

Use the PhpMyAdmin instance with the MySQL root password set above to create a new user and make sure you select to create a database with the same name. After this, import your database files using the import option of PhpMyAdmin.

Once you have imported the database modify the kvht_options table so that the records with the following name are updated accordingly:

name value
siteurl <docker-host-hostname-or-IP-address>:8080
home <docker-host-hostname-or-IP-address>:8080
upload_path /var/www/html/wp-content/uploads

Note: The table name may have a different prefix to mine or no prefix at all.

At this point if you have any media which is embedded using an absolute URL to your actual live Word Press site then you need to update individual posts to make the URL’s server relative. This is not taken care of in this post as I always use server root relative paths for this type of media. A quick trick would be to do an appropriate regex find and replace in the exported SQL file before the import.

Now we need to run an instance of the Word Press image but using our Word Press files.

docker run --name wp-blog --link wp-mysql:mysql -p 8080:80 -e MYSQL_ENV_MYSQL_USER=database_user -e MYSQL_ENV_MYSQL_PASSWORD=database_user_password -e MYSQL_ENV_MYSQL_DATABASE=database_name -v /path/to/wordpress/files:/var/www/html -d wordpress

At this point you should be able to access your Word Press site on port 8080 of the Docker host.

For those that use boot2docker (even through docker-machine) your Word Press file directory may not be writeable by the Word Press docker container. To fix this I built the Word Press image directly from the associated Dockerfile with an extra command to modify the www-data user inside the image so that it’s UID matched a user’s UID on the source file systems directory that had write access to the Word Press files.