After some deliberation, I’ve moved this site to a Docker container. My intention is to have all my web sites and services Dockerised, and sitting behind a reverse proxy server (originally Apache, but see bottom of post for NGINX config). Here are some issues I enountered and what was required to fix them.
Creating containers for the WordPress site
I have some services already running on Docker so I had that installed already. So I created a project directory where I store a docker-compose.yml file to start up my containers.
$ git clone https://github.com/martynbiz/wordpress-docker project_dir
$ cd project_dir
$ cp docker-compose.yml-example docker-compose.yml
$ cp uploads.ini-example uploads.ini
I made the neccessary changes to the docker-compose.yml and uploads.ini files, then created my containers.
$ docker-compose up -d
...
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9bc5f2eea5db wordpress:5.5.0-php7.3-apache "docker-entrypoint..." 10 seconds ago Up 10 seconds 0.0.0.0:8001->80/tcp martynbiz_wordpress_1
a3e222f2e684 mysql:5.7 "docker-entrypoint..." 10 seconds ago Up 10 seconds 3306/tcp, 33060/tcp martynbiz_db_1
I then created and enabled a proxypass for incoming traffic on this domain to the port assigned to the container port.
Setting up the apache config ProxyPass
Debugging apache configuration isn’t my strong point as it’s not my day to day job. So far, this is working out:
<Virtualhost *:80>
ServerName www.martyn.biz
ServerAlias martyn.biz
ProxyPreserveHost On
<Proxy http://localhost:8001/*>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8001/ nocanon
ProxyPassReverse / http://localhost:8001/
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.martyn.biz [OR]
RewriteCond %{SERVER_NAME} =martyn.biz
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</Virtualhost>
Error: Block mixed content
This was on the installation page so no tables had been created yet. It seems I had to add the following to the top of wp-config.php ensure assets (stylesheets, etc) were requested over HTTPS:
<?php
if ( (!empty( $_SERVER['HTTP_X_FORWARDED_HOST'])) || (!empty( $_SERVER['HTTP_X_FORWARDED_FOR'])) ) { $_SERVER['HTTPS'] = 'on'; }
...
Anyway, next step is to move more sites to containers as well as the server software. Ideally keeping the host as bare as possible.
UPDATE
I have since installed Nginx to handle the reverse proxies. I found with other apps trying to configure them correctly in Apache to handle headers and be sent over HTTPS a bit of a pain. With Nginx, this was a breeze. Seems that Nginx definetely works better out the box for this sort of thing.
Below is my Nginx config file to do the reverse proxy for this site:
server {
server_name martyn.biz;
index index.html;
location / {
proxy_pass http://localhost:8099/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
client_max_body_size 0;
access_log /var/log/nginx/martynbiz.access.log;
error_log /var/log/nginx/martynbiz.error.log;
}
location /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
listen [::]:443 ssl http2; # managed by Certbot
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/martyn.biz/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/martyn.biz/privkey.pem; # managed by Certbot
ssl_trusted_certificate /etc/letsencrypt/live/martyn.biz/chain.pem;
}
server {
if ($host = martyn.biz) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name martyn.biz;
return 404; # managed by Certbot
}