WordPress in a Docker container

Running WordPress in a container is tricky.  It is tricky because WordPress will hardcode the site’s domain in URLs.  WordPress is happy with this situation.  The container does not know the virtual name it will be given and so URLs contain a domain string i.e. 192.168.0.3.  I have failed to do this several times but I think I have got close this time.

I use Let’s Encrypt, TLS and SNI with Apache to point to services running in Docker containers.  I prefer that services do not encrypt services because my poor server should not have to encrypt twice.  The technique I use to point to containers is called a reverse proxy.

At the interface of the reverse proxy we can change all sorts of things.  This is my Apache config for WordPress:

VirtualHost *:80>
  ServerAdmin williams@c3iq.co.uk
  ServerName bob.domain.om
  ErrorLog /usr1/home/frank/virtual/bob/logs/error_log
  CustomLog /usr1/home/frank/virtual/bob/logs/access_log common

  Redirect / https://bob.domain.com/
</VirtualHost>

<VirtualHost *:443>
  Protocols h2 http/1.1
  ServerAdmin williams@c3iq.co.uk
  ServerName bob.domain.com
  ErrorLog /usr1/home/frank/virtual/bob/logs/error_log
  CustomLog /usr1/home/frank/virtual/bob/logs/access_log common

  #AddType application/x-httpd-php .php

  ProxyRequests Off
  ProxyPreserveHost Off

  #SSLProxyCheckPeerCN off
  #SSLProxyCheckPeerExpire off
  #SSLProxyVerify none
  #SSLProxyEngine on

  Substitute "s|http://192.168.0.3:8002|https://bob.domain.com|n"
  Substitute "s|http:\/\/192.168.0.3:8002|https:\/\/bob.domain.com|n"
  Substitute "s|http%3A%2F%2F192.168.0.3%3A8002|http%3A%2F%2Fbob.domain.com|n"
  Substitute "s|http://0.gravatar.com|https://0.gravatar.com|n"
#  Substitute "s|http://|https://|n"

  FilterDeclare NEWPATHS
  FilterProvider NEWPATHS SUBSTITUTE "%{Content_Type} =~ m|^text/html|"
  FilterProvider NEWPATHS SUBSTITUTE "%{Content_Type} =~ m|^text/css|"
  FilterProvider NEWPATHS SUBSTITUTE "%{Content_Type} =~ m|^text/javascript|"
  FilterProvider NEWPATHS SUBSTITUTE "%{Content_Type} =~ m|^application/javascript|"
  FilterChain NEWPATHS

  Header edit Location ^http://192.168.0.3 https://bob.domain.com
  Header set X-Frame-Options "SAME-ORIGIN"

  <Location "/">
    ProxyPass http://192.168.0.3:8002/
    ProxyPassReverse http://192.168.0.3:8002/
    ProxyPassReverseCookieDomain 192.168.0.3 bob.domain.com
    RequestHeader unset Accept-Encoding

    #AllowMethods GET POST OPTIONS PUT

    AllowOverride All
    Require all granted

    #Require ip 192.168
  </Location>

  SSLEngine on
  SSLProtocol -ALL +TLSv1.2
  SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:!RC4:!DES:!3DES:+HIGH:+MEDIUM
  SSLCertificateKeyFile /etc/letsencrypt/live/c3iq.co.uk/privkey.pem
  SSLCertificateFile /etc/letsencrypt/live/c3iq.co.uk/fullchain.pem

  <Files ~ "\.(cgi|shtml|phtml|php?)$">
     SSLOptions +StdEnvVars
  </Files>
</VirtualHost>

Please, comment if you see a mistake or know of a better pattern.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.