Two SSL-Enabled WordPress Sites on one EC2 Instance with Docker (pt.1)
By WedBot
When I created this site, I wanted to make sure that I could run a segregated technical blog away from the human site, as well as enable HTTPS for security. This 2 part article will walk you through how to run 2 SSL-Enabled WordPress installations on a single server with Docker, using LetEncrypt for certification, and Nginx as a reverse proxy.
A Reverse Proxy?!
I decided that the technical blog should be WordPress, and whilst I decided how the main site would be implemented, I should also put a WordPress installation in place there too. The challenge was running 2 websites listening on port 80 on the same server, with 2 different subdomains. This is where Nginx comes into play – a reverse proxy will take incoming requests, and route them to the correct destination. This is even easier when combined with Docker.
Docker Configuration
I’m using a docker-compose file to takes care of dependencies and allow data to be stored back to the EC2 instance using volumes. It’s important to remember that Docker containers are ephemeral, so no data should be stored in the container itself. Eventually persisted data should be moved onto EBS so that it will exist even when the underlying EC2 instance is destroyed.
You’ll see below that I’m using version 3.3 of the docker-compose.yml format. As I’m relatively new at all this, I’m not too bothered about backwards compatibility of my files. You can see a few important things:
- Volumes are mapped for
db1
andsite1
, allowing them to write data onto the host of the containers – in this case the EC2 instance. depends_on
forsite1
is set todb1
, ensuring startup dependencyworking_dir
is set for containersite1
. This is probably the most important setting, to get WordPress to write to a specific directory.
version: '3.3'
services:
db1:
image: mysql:5.7
restart: always
volumes:
- ./site1_db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: wordpress
MYSQL_USER: userword
MYSQL_PASSWORD: password
site1:
image: wordpress:5-fpm
depends_on:
- db1
restart: always
working_dir: /var/www/html/site1
volumes:
- ./site1_wp:/var/www/html/site1
environment:
WORDPRESS_DB_HOST: db1:3306
WORDPRESS_DB_USER: username
WORDPRESS_DB_PASSWORD: password
The config above will set up one database and WordPress instance, and so you will need to copy db1
and site1
to create a second one. Don’t forget to change your working directory and volume to a different location for your second instances. You will end up with a docker-compose file that looks like below.
services:
db1:
# skipped for clarity
site1:
# skipped for clarity
db2:
# skipped for clarity
site2:
# skipped for clarity
website:
image: nginx
depends_on:
- db1
- site1
- db2
- site2
restart: always
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./logs:/var/log/nginx
- ./site1_wp:/var/www/html/site1
- ./site2_wp:/var/www/html/site2
You can see that I’ve also added the Nginx container config called website
, and there are several important volumes configured.
- There is also a
logs
directory so that you will be able to access logs from EC2 rather than having to remote into the container. - I have specified the directories of both WordPress containers, so that Nginx can serve up the content from the host.
- A nginx.conf file location which will be passed to the Nginx service in the container.
In Part 2 of this article I will show you how to configure your Nginx config file to pick up and serve both WordPress sites, and how to enable HTTPS.