This multi-container Docker app is orchestrated with Docker Compose for rapid and modular deployment that fits in any microservice architecture.
It creates a WordPress website on a MySQL database and an NGINX web server, with Certbot by the Electronic Frontier Foundation (EFF) for obtaining and renewing a signed SSL/TLS certificate on a given root domain from Let’s Encrypt, a non-profit Certificate Authority by the Internet Security Research Group (ISRG).
A detailed walk-through is available here.
Get started in three simple steps:
- Download a copy of the app;
- Create the environment variables for the MySQL root password and the WordPress database settings; and
- Docker Compose to start the app.
Download a copy of the app with git clone
. Be sure to pass the --recurse-submodules
argument to initialise and update each submodule in the repository.
$ git clone --recurse-submodules https://github.com/kurtcms/docker-compose-wordpress-nginx-mysql /app/docker-compose-wordpress-nginx-mysql/
Docker Compose expects the MySQL root password, the WordPress database name, username and password as environment variables in a .env
file in the same directory.
Be sure to create the .env
file.
$ nano /app/docker-compose-wordpress-nginx-mysql/.env
And define the variables accordingly.
# MySQL root password
MYSQL_ROOT_PASSWORD='(redacted)'
# WordPress database name, username and password
MYSQL_WORDPRESS_DATABASE='kurtcms_org'
MYSQL_WORDPRESS_USER='kurtcms_org'
MYSQL_WORDPRESS_PASSWORD='(redacted)'
With Docker Compose, the app may be provisioned with a single command.
Install Docker and Docker Compose with the Bash script that comes with app.
$ chmod +x /app/docker-compose-wordpress-nginx-mysql/docker-compose/docker-compose.sh \
&& /app/docker-compose-wordpress-nginx-mysql/docker-compose/docker-compose.sh
A dummy SSL/TLS certificate and private key will need to be created for NGINX to start service, and for Certbot to subsequently obtain a signed SSL/TLS certificate from Let's Encrypt by answering a HTTP-01 challenge.
Create the dummy certificate before obtaining a signed one with the Bash script that comes with app.
$ chmod +x /app/docker-compose-wordpress-nginx-mysql/certbot/certbot.sh \
&& /app/docker-compose-wordpress-nginx-mysql/certbot/certbot.sh
Enter the root domain and the email address for registration and recovery when prompted.
Start the containers with Docker Compose.
$ docker-compose -f /app/docker-compose-wordpress-nginx-mysql/docker-compose.yml up -d
Stopping the containers is as simple as a single command.
$ docker-compose -f /app/docker-compose-wordpress-nginx-mysql/docker-compose.yml down
With the Docker containers up and running, WordPress will be reachable at the localhost address on TCP port 443 i.e. HTTPS, to which TCP port 80 i.e. HTTP will be redirected. Follow the instructions on screen to set up WordPress. Alternatively the MySQL database and WordPress content can be restored from an existing backup.
The MySQL database, the WordPress content as well as the signed SSL/TLS certificate and its corresponding private key are stored in separate Docker volume
under /var/lib/docker/volumes/
.
/var/
└── lib/
└── docker/
└── volumes/
├── docker-compose-wordpress-nginx-mysql_certbot/
├── docker-compose-wordpress-nginx-mysql_mysql/
└── docker-compose-wordpress-nginx-mysql_wordpress/
MySQL comes with a tool for logical backup. It produces a set of SQL statements that can be executed to reproduce the original database object definitions and table data.
Back up an existing MySQL database in a container.
$ docker exec -it mysql mysqldump \
--user root \
--password \
kurtcms_org > kurtcms_org.sql
Restore a database from an existing backup.
$ docker exec -it mysql mysql \
--user root \
--password \
kurtcms_org < kurtcms_org.sql
WordPress plugins and themes, as well as media files uploaded by users are housed under wp-content
in the WordPress directory. Backing up and restoring them is as simple as making a copy of this directory and moving it to the WordPress container.
Making a copy of the wp-content
directory.
$ cp -r /var/lib/docker/volumes/docker-compose-wordpress-nginx-mysql_wordpress/_data/wp-content \
/app/docker-compose-wordpress-nginx-mysql/
Restoring it from an existing backup.
$ cp -r /app/docker-compose-wordpress-nginx-mysql/wp-content/ \
/var/lib/docker/volumes/docker-compose-wordpress-nginx-mysql_wordpress/_data/
Certbot is instructed by Docker Compose to attempt a SSL/TLS certificate renewal every 12 hours, which should be more than adequate considering the certificate is valid for 90 days.
NGINX is instructed to reload its configuration every 24 hours to ensure the renewed certificate will come into effect at most 12 hours after a renewal, which should also be well in advance of an impending expiry.
Edit the docker-compose.yml
should these intervals need to be adjusted.
$ nano /app/docker-compose-wordpress-nginx-mysql/docker-compose.yml
Modify the values as appropriate.
nginx:
...
command: "/bin/sh -c 'while :; do sleep 24h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
...
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"