Running WordPress in Kubernetes – Enabling SSL

In this post, I will cover how to enable SSL for your WordPress site. There are countless reasons why you would want to enable SSL on your site, so I won’t go into those over here. However, there are several different ways to enable SSL for your WordPress site.

Possible Solutions

Option 1: Use one of the official WordPress Docker images that already contain a web server (e.g. wordpress:5.5.2-php7.4-apache). Mount all the SSL certs and the necessary web server configuration to the appropriate paths in the WordPress deployment spec.

Option 2: If you choose to use one of the official WordPress Docker images that don’t contain a webserver, then add a webserver container to your WordPress deployment spec. The webserver container will act as a proxy to the WordPress container (i.e. all requests will be first received by the webserver container, which will then forward to the WordPress container. Once the WordPress container has processed the request, the response will be sent back to the webserver container which will reply back to the original external request). Just like in the previous option, you will need to mount all the SSL certs and necessary web server configuration to the appropriate paths in the webserver container section of the WordPress deployment spec.

General Methodology

Regardless of which option you choose, here are the things you need to do:

  1. Copy SSL certs to the same NFS server where you host your WordPress wp_content files.
  2. Determine which webserver technology you want to use and what configuration you will need to enable SSL on it.
  3. Upload webserver configuration also to the same NFS server where you host your WordPress wp_content files.

Between the two options, I prefer option 1 because it is both simple and easy to debug. I will show how to enable SSL for the official WordPress Docker image that comes with Apache installed (i.e. wordpress:5.5.2-php7.4-apache).

SSL Certs

Upload all of the SSL certs and keys to the same Network File Share where your WordPress content is stored at. You should be uploading at least 1 .cert/.crt file and 1 .key file. Depending on who signed your certificate, you may also need to upload 1 ca_bundle .cert/.crt file. The locations of these files will need to be filled in WordPress Deployment config as follows:

  • Replace “<File share path for ca_bundle.crt>” with location to ca_bundle.crt on NFS. If you don’t need to upload ca_bundle.crt, then remove this config value from both Apache config and WordPress Deployment spec.
  • Replace “<File share path for certificate.crt>” with location to certificate.crt on NFS
  • Replace “<File share path for private.key>” with location to private.key on NFS

Apache Config

Create a file containing the following content with the name default.conf. Upload this file to the same Network File Share where your WordPress content is stored at. Replace “<Azure File share path for default.conf>” with the location of the .conf file in WordPress Deployment config.

<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	ServerName myblog.com
	ServerAdmin [email protected]

        # Redirect all traffic sent to HTTP to HTTPS
	Redirect / https://myblog.com/

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:443>
    ServerName myblog.com

    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on
    # You may or may not need to specify SSLCACertificate file depending on the signer of your certificate.
    SSLCACertificateFile "/var/www/certs/ca_bundle.crt"
    SSLCertificateFile "/var/www/certs/certificate.crt"
    SSLCertificateKeyFile "/var/www/certs/private.key"
</VirtualHost>

WordPress Deployment Config

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  replicas: 3
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      # podAntiAffinity declaration to spread pods (evenly) across nodes
      containers:
      - name: wordpress
        image: wordpress:5.5.3-php7.4-apache
        cmd: ["/bin/bash"]
        args: ["-c", "a2enmod ssl && docker-entrypoint.sh apache2-foreground"]
        # regular env and ports declarations
        volumeMounts:
          - name: azure-file
            subPath: "<File share path for wp-content>"
            mountPath: /var/www/html/wp-content
          - name: azure-file
            subPath: "<File share path for ca_bundle.crt>"
            mountPath: /var/www/certs/ca_bundle.crt
          - name: azure-file
            subPath: "<File share path for certificate.crt>"
            mountPath: /var/www/certs/certificate.crt
          - name: azure-file
            subPath: "<File share path for private.key>"
            mountPath: /var/www/certs/private.key
          - name: azure-file
            subPath: "<File share path for default.conf>"
            mountPath: /etc/apache2/sites-enabled/000-default.conf
      volumes:
      - name: azure-file
        persistentVolumeClaim:
          claimName: azure-file

Leave a Reply

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