With the following “Docker recipe”, you will set up a Docker node running separate WordPress installation on two domains or subdomains. This setup is pretty much production ready, with:
- nginx reverse proxy by Jason Wilder that automatically routes traffic to new containers that are created with the VIRTUAL_HOST=sub.domain.com environment variable. This nifty container performs a similar function to Traefik or HAProxy, but it is amazingly simple to use.
- letsencrypt-nginx-proxy-companion by Yves Blusseau that obtains an SSL certificate from Let’s Encrypt, the free Certificate Authority, when you specify the LETSENCRYPT_HOST and LETS_ENCRYPT_EMAIL environment variables on any application container (i.e. WordPress) that needs to be served over HTTPS. The companion even pings Let’s Encrypt every 90 days to automatically renew your certificates!
- Official MariaDB and WordPress containers from the docker-library, approved by the Docker Store.
From your DNS provider, which may be your domain registrar or a third-party service such as CloudFlare, create A records for the domains and/or subdomains where you want to install WordPress, towards the outward facing IP address of your Docker host. Use a short time to live (TTL), such as 3,600 seconds or less to reduce the time that the DNS records will take to propagate.
Find out how to set up your Docker environment on Linux here. You need SSH access to your server, which should run Ubuntu, Debian, Fedora or CentOS in order to use the community edition of Docker. If your VPS provider, such as DigitalOcean provides a “one click install”, it’s okay to use that as well.
Create a swap file to prevent your MariaDB or WordPress containers from running out of memory under load.
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo cp /etc/fstab /etc/fstab.bak
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
You can execute docker commands as root, but it’s recommended to create a normal user account and add that user to the docker group. For security reasons, you shouldn’t generally be performing tasks on your Linux box as root. Instead, add a regular user account to the sudo (Ubuntu) or wheel (CentOS) group so you can execute commands as sudo.
sudo useradd dockeruser
sudo usermod -aG docker dockeruser
sudo usermod -aG sudo dockeruser
login dockeruser
1. First, create a Docker network. This enables container DNS, which allows containers to communicate with one another by name.
docker network create dockerwp
docker run --name nginx-proxy --net dockerwp -p 80:80 -p 443:443 -v ~/certs:/etc/nginx/certs -v /etc/nginx/vhost.d -v /usr/share/nginx/html -v /var/run/docker.sock:/tmp/docker.sock:ro --label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy -d --restart always jwilder/nginx-proxy
docker run --name letsencrypt-nginx-proxy-companion --net dockerwp -v ~/certs:/etc/nginx/certs:rw -v /var/run/docker.sock:/var/run/docker.sock:ro --volumes-from nginx-proxy -d --restart always jrcs/letsencrypt-nginx-proxy-companion
docker run --name mariadb1 --net dockerwp -v mariadb1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=supersecret -e MYSQL_DATABASE=db1 -e MYSQL_USER=db1user -e MYSQL_PASSWORD=secret -d --restart always mariadb
docker run --name mariadb2 --net dockerwp -v mariadb2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=supersecret -e MYSQL_DATABASE=db2 -e MYSQL_USER=db2user -e MYSQL_PASSWORD=secret -d --restart always mariadb
printf "file_uploads = On\nmemory_limit = 64M\nupload_max_filesize = 64M\npost_max_size = 64M\nmax_execution_time = 600" > ~/uploads.ini
docker run --name wordpress1 --net dockerwp -v wordpress1:/var/www/html -v ~/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini -e WORDPRESS_DB_HOST=mariadb1:3306 -e WORDPRESS_DB_NAME=db1 -e WORDPRESS_DB_USER=db1user -e WORDPRESS_DB_PASSWORD=secret -e VIRTUAL_HOST=sub.domain1.com -e LETSENCRYPT_HOST=sub.domain1.com -e [email protected] -d --restart always wordpress
docker run --name wordpress2 --net dockerwp -v wordpress2:/var/www/html -v ~/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini -e WORDPRESS_DB_HOST=mariadb2:3306 -e WORDPRESS_DB_NAME=db2 -e WORDPRESS_DB_USER=db2user -e WORDPRESS_DB_PASSWORD=secret -e VIRTUAL_HOST=sub.domain2.com -e LETSENCRYPT_HOST=sub.domain2.com -e [email protected] -d --restart always wordpress