☁️ Helm chart that uses Ansible to set up a hardened WordPress. Customized for Chicago Gang History.
Go to file
vhs 3f69a670af
feat: 🎸 support ads.txt for ad transparency
2021-01-25 00:28:04 +08:00
.gitlab/issue_templates re-add --> 2020-07-02 15:49:28 +02:00
templates use "required" for mu_cron secret that needs to be overwritten 2021-01-06 09:03:44 +01:00
wp-cli-docker feat: 🎸 support ads.txt for ad transparency 2021-01-25 00:28:04 +08:00
wp-docker Resolve "Show original external IPs in kubectl logs" 2020-09-09 10:12:44 +00:00
.gitignore move mu_cron secret to mu_cron settings so it cannot cause problems for people that do not use it 2021-01-04 15:42:10 +01:00
.gitlab-ci.yml remove "docker" tag from CI jobs 2020-06-09 09:40:09 +02:00
.helmignore Moved repository without moving history 2020-06-09 09:28:33 +02:00
CHANGELOG.md Release version 0.1.6 2021-01-14 11:11:48 +01:00
Chart.yaml Release version 0.1.6 2021-01-14 11:11:48 +01:00
LICENSE Moved repository without moving history 2020-06-09 09:28:33 +02:00
README.md Merge branch '61-squelch-cannot-set-fs-attributes-on-a-non-existent-symlink-target-message' into 'master' 2021-01-12 13:51:14 +00:00
RELEASING.md Release version 0.1.3 2020-06-18 16:53:11 +02:00
delete.sh remove subPath, fix comments, remove tmp directory after using it 2020-07-01 17:42:30 +02:00
install.sh.example update install.sh.example to accept extra command line arguments 2020-12-18 11:42:03 +01:00
requirements.yaml Moved repository without moving history 2020-06-09 09:28:33 +02:00
test-install.sh.example explain that you need to edit values-local.yaml.example, remove trailing spaces 2020-06-23 09:49:31 +02:00
values-local.yaml.example use "required" for mu_cron secret that needs to be overwritten 2021-01-06 09:03:44 +01:00
values.yaml Release version 0.1.6 2021-01-14 11:11:48 +01:00
variables.sh actually cut to 63 bytes, not characters 2021-01-06 17:33:32 +01:00




  1. Make sure you have kubernetes-cli and helm (version >= 3) installed on your development machine

  2. Make sure you have a running kubernetes cluster that your kubectl is connected to. Check this by running kubectl version. It should tell you the client and server version of Kubernetes.

  3. The redis and MariaDB helm charts live in a custom Bitnami chart repository (the ones in the helm stable repository are deprecated and moved there). Get the repository by running:

    $ helm repo add bitnami https://charts.bitnami.com/bitnami
  4. The chart assumes you have nginx ingress running in IP range If you do, the access logs will show remote IP addresses from the X-Forwarded-For header. Otherwise, the proxy IP address is shown in the access logs.

    If you don't use nginx ingress and you enable mu_cron, make sure to block the path from wordpress.mu_cron.cronjob.path from outside traffic.

Start WordPress on Kubernetes


Copy values-local.yaml.example to values-local.yaml. This file contains a lot of variables that you can change to adjust the WordPress installation to your needs.

For a simple WordPress installation, you only need to edit the following values:

Parameter Description Default
ansibleVars.WP_URL The URL of your WordPress website http://localhost
ansibleVars.WP_TITLE The title of the site Demo WP
ansibleVars.WP_THEME_ACTIVE A slug for the theme you want to install on your site (can also be changed through interface) twentytwenty
ansibleVars.WP_EMAIL The administrator's email adress youremailhere@example.com
database.db.user Database user wordpress
database.db.password wordpress db user password You really need to set this
database.db.rootUser.password root user password You really need to set this
database.db.replicationUser.password replication user password You really need to set this

You can read the descriptions of the other variables in values-local.yaml.example and of even more variables in values.yaml.

Note about theme fallback

If there is no theme available to activate in wp_content then the fallback theme will be used This is set by wordpress.site.theme_fallback from values.yaml

Note about the ansibleVars:

All the variables under ansibleVars are used by the ansible playbook that is run in the init container to configure the WordPress website. You can find their default values in the values.yaml file. You can override single values of ansibleVars.<any variable> in your values-local.yaml file. NOTE: if you would want to override variables in ansibleSecrets, you have to copy the whole ansibleSecrets string to values-local.yaml!


  1. Install the helm dependencies by typing helm dep update

  2. Start WordPress by typing running install.sh.

    NOTE: if you override the image or initImage tags in values.yaml, installation with this script ignores that.

See What happens when I install this? for information on what happens now.


To undo an installation and remove all traces of it ever existing, use the delete.sh script. NOTE: use this at your own risk! Your databases, uploads, etc. will be removed for ever!


To debug the init container, you can use kubectl logs, but because it is not the default container, you need to use the -c argument as follows:

$ kubectl logs <pod> -c init-wordpress

What happens when I install this?

Installed pods

Helm will set up the kubernetes pods that are needed to run your website:

  1. A WordPress pod that serves the site
  2. Two MariaDB pods running the database (master-slave setup by default, unless you changed this in values-local.yaml)
  3. If you configured Redis, a Redis pod is also set up

The MariaDB and Redis pods are documented in the official helm charts repository, this file documents the WordPress pod that will serve the site.

Init container

This chart provides an "init container" for the WordPress pod. This container sets up the wordpress. Each time a pod is (re)started, the init container:

  1. Downloads WordPress to a temporary directory
  2. Configures that fresh WordPress
  3. Downloads and activates the plugins specified in ansibleVars.wordpress_default_plugins

WordPress setup

After the init container is done, persistent volumes are mounted:

  • wpContentDir contains the wp-content directory and is persistent over pod restarts
  • wpUploadDir contains the uploads directory that is usually a subdirectory of the wp-content dir and is persistent.
  • A configmap containing the .htaccess file for the uploads dir is mounted in wpUploadDir/.htaccess

Importing an existing WordPress site

We assume you have:

  • A running kubernetes cluster
  • kubectl installed on your machine and configured to connect to your running cluster.
  • tar installed
  • A database dump of your old website's database called dump.sql.
  • The contents of the wp-content folder (usually at /var/www/html/wp-content) in a local directory called wp-content.

Make sure the copy of the wp-content directory and the database dump are made at the same time.

We will go through the following steps:

  1. Set up a new WordPress site by installing this chart
  2. Import the Database
  3. Import the files from wp-content

Set up a new WordPress site

Follow the instructions under Start WordPress on Kubernetes

You might have to edit the following variables to reflect your current site's:

  • Set DB_PREFIX to the database prefix that your current WordPress uses
  • Set WP_VERSION to the version of your current WordPress site.
  • Check if your current WordPress uses Redis. This is usually the case when you have the redis-cache plugin installed. If so, enable redis in your values-local.yaml by setting redis.enabled to true.

After installing, check if your site is available at the URL you specified in values-local.yaml. When it is, type helm ls to find the name of your deployment. In the rest of this document we will assume that your WordPress deployment is named wordpress-master.

Import the database

Make sure to remove all explicit URLs to your site from the database. If you host your site on example.com, WordPress tends to put links in the database as https://example.com/<link to your post> or http://example.com/<link to your post>. If you want to try this new deployment on a different domain, that will not work. To fix this, search for https://example.com in your database and remove it. Repeat this step for http://example.com.

When your database file is ready, import it with the following command:

$ kubectl exec -i wordpress-master-mariadb-master-0 -- mysql -uwordpress -p<your password> --database=wordpress_db < dump.sql

A breakup of the command:

  • kubectl exec means you want to execute a command in a container
  • -i makes sure that stdin is passed to the container. This means that we can use < dump.sql to import the database export from your local system.
  • We assume your database is running in a pod named wordpress-master-mariadb-master-0.
  • -- tells kubectl to stop interpreting command line arguments as kubectl arguments
  • mysql executes the mysql command in the container, with the following arguments:
    • -uwordpress sets the MySQL user to wordpress
    • -p provides the prassword of the wordpress user
    • --database=wordpress_db selects the wordpress_db database.
  • < dump.sql reads the file dump.sql and inserts it into the mysql command. Change this if your MySQL database dump has a different filename.

Import the files from wp-content/uploads

Similar to how you would normally use scp to copy files to a server, you can use kubectl cp to copy files to your wordpress pod. Make sure that you copy your uploads directory contents to the directory you have configured as the wpUploadDir in the values-local.yaml. If you haven't configured it, it defaults to /var/www/wp-uploads-mount. Also make sure it does not contain a .htaccess file because that is provided by this chart.

run kubectl get pods to figure out what the name is of the pod running WordPress:

$ kubectl get pods
NAME                                                 READY     STATUS    RESTARTS   AGE
wordpress-master-0                               1/1       Running   0          20d
wordpress-master-mariadb-master-0                1/1       Running   9          20d
wordpress-master-mariadb-slave-0                 1/1       Running   12         20d

In this case, we have 2 mariadb pods and one WordPress pod. We can copy the wp-content contents to the pod with the following command:

$ kubectl cp uploads/ wordpress-master-0:/var/www/wp-uploads-mount

You'll have to change the ownership of the files to UID 33 (the www-data user in the WordPress container):

$ kubectl exec -it wordpress-master-0 -- chown -R 33:33 /var/www/wp-uploads-mount

Note: this will say chown: changing ownership of '/var/www/wp-uploads-mount/.htaccess': Read-only file system. Don't worry, that's the mounted .htaccess file. All the other files' ownership will have changed.

Known issues

Take a look at https://open.greenhost.net/openappstack/wordpress-helm/-/issues for issues that are already reported.


Most of this helm chart was made by following this and this.