Introduction
I had a couple of WordPress sites I wanted to dockerize and move over to my new server. This is the configuration I used to deploy them to my new server as described here.
I’m using the official wordpress
and mysql
images and don’t need to build anything, so all I need to deploy the app is a docker-compose.yml
file and a couple of .env
files.
The docker-compose.yml file
I’m using the wordpress:5.4.1
(also tagged as wordpress:5.4.1-apache
) which uses an Apache server and serves the app on port 80. Port 8080 is mapped to my host.
version: '3.7'
services:
wordpress:
image: wordpress:5.4.1
restart: always
volumes:
- wordpress:/var/www/html
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
env_file:
- wordpress.env
depends_on:
- db
db:
image: mysql:5.7.30
restart: always
volumes:
- data:/var/lib/mysql
env_file:
- db.env
volumes:
data:
wordpress:
Note that we need to specify the WORDPRESS_DB_HOST
and the name we pass needs to match the service name we’ve given mysql
, which is db
in this case.
We’re creating two named volumes, one for the WordPress files (wordpress:/var/www/html
) and one for the database data (data:/var/lib/mysql
).
Lastly we’re using two .env
files, db.env
and wordpress.env
which will hold our database credentials which we’ll later use to connect the site to the database.
The .env files
In the db.env
file I’ve specified the following:
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_DATABASE=your_db_name
MYSQL_USER=your_username
MYSQL_PASSWORD=your_user_password
And in the wordpress.env
file:
WORDPRESS_DB_NAME=your_db_name
WORDPRESS_DB_USER=your_username
WORDPRESS_DB_PASSWORD=your_user_password
The above can be any names and passwords you want but they need to match.
Note that the .env
files can be named anything you want as long as they corresponds to the name supplied in the docker-compose.yml
file.
Note: don’t commit these files to your version control system, I usually ignore all
*.env
files in my.gitignore
file.
Running the blog locally
Next to make sure everything is set up correctly run the app locally with:
docker-compose up
You should be able access the WordPress 5 minute install page by visiting http://localhost:8080
. Go through the steps to make sure everything is working and WordPress can connect to the database.
Migrating an existing app
In my case I was moving a standard WordPress installation from SiteGround servers onto my DigitalOcean droplet and dockerizing it. I decided to use the duplicator plugin.
First install the duplicator plugin on your old WordPress site and create and download a new duplicator package which consists of an installer.php
file and an archive zip file.
With the free duplicator version you need an empty directory to install the site in, so we’ll need to delete all the files from the /var/www/html/
directory within the container. First find the container name:
docker ps
# output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cd241e74dc25 wordpress:5.4.1 "docker-entrypoint.s…" 4 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp your_project_wordpress_1
33739a43fad5 mysql:5.7.30 "docker-entrypoint.s…" 4 minutes ago Up 2 minutes 3306/tcp, 33060/tcp your_project_db_1
Then attach to the process with:
docker exec -it your_project_wordpress_1 bash
# output:
root@cd241e74dc25:/var/www/html#
Next you can delete all the files and directories within the html
directory:
rm -rf /var/www/html/*
ls -a
exit
Now copy the archive zip file and installer.php
from your host into the html
directory (note you’ll need to scp
the files into your remote server first and cd
into the directory):
docker cp installer.php your_project_wordpress_1:/var/www/html/
docker cp long_name_of_archive.zip your_project_wordpress_1:/var/www/html/
Visit http://yourwebsite.com/installer.php
and follow the instructions. You’ll need to fill in the database fields with the credentials you put in the db.env
file.
The duplicator files will be deleted once you’re done and you can double check that with:
docker exec your_project_wordpress_1 ls -a
Your website and database should now be all up to date.
Too many redirect error
If you’re setting up SSL on your website (which you definitely should be) you may run into an ERR_TOO_MANY_REDIRECTS
error when trying to access some or all of the pages on your WordPress site.
I was running into this issue as I’m using an NGINX reverse proxy to serve my WordPress site and redirect to https
. WordPress is then being served by an Apache server (this is how the official wordpress
image used above is configured), and I was missing one small configuration to make this setup work.
To fix this edit your wp-config.php
file and at the top add:
$_SERVER['HTTPS'] = 'on';
I had another reference to $_SERVER['HTTPS'] = 'on'
within an if statement in my wp-config.php
file which I deleted as it wasn’t being picked up. Your config file may not have this though.
After that everything worked fine!