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.comenvironment 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
LETS_ENCRYPT_EMAILenvironment 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.
Many thanks to the maintainers of these containers, who have open sourced the Dockerfiles on GitHub and are well reputed in the community. The only things you really need to change for the recipe below to be ready to go are the parameters highlighted in blue.
Create DNS Records
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
Create non-root user account for Docker (recommended)
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
Run the Nginx-Proxy, MariaDB, WordPress containers
1. First, create a Docker network. This enables container DNS, which allows containers to communicate with one another by name.
docker network create dockerwp
2. Start the Nginx proxy.
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
3. Start the Let’s Encrypt Nginx Proxy Companion.
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
4. Start the MariaDB containers.
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
5. Enable large file uploads in WordPress (> 2 MB).
printf "file_uploads = On\nmemory_limit = 64M\nupload_max_filesize = 64M\npost_max_size = 64M\nmax_execution_time = 600" > ~/uploads.ini
6. Start the WordPress containers.
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 LETSENCRYPT_EMAILfirstname.lastname@example.org -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 LETSENCRYPT_EMAILemail@example.com -d --restart always wordpress
Now that you have two secure, containerized WordPress installations, you have the capability to add a third, forth or more. For further exploration, why not try hosting other applications besides WordPress behind the Nginx proxy? Any software that is available as a Docker image and listens on port 80 is possible. This simple, yet powerful architecture is useful for hosting multiple containerized applications with a single IP, allowing you to do even more with fewer cloud instances.
My first post is a copy of another blog, just to get it saved for backup. Here is the source: https://autoize.com/multiple-wordpress-sites-docker/