5

If I'm running Wordpress in a Kubernetes environment, whereby the code is part of a Docker image and someone tries to add a plugin through the Wordpress admin, I don't expect that will work very well, as the plugin will only be installed on the container that's hit when they add the plugin, right?

Is my approach of building the code into an image a misstep? Another approach I'd considered was a volume that holds the code, which would handle this use case well. Is there a discussion of such things I could read somewhere?

quickshiftin
  • 2,025
  • 5
  • 27
  • 41

1 Answers1

2

Assuming that you are required to allow wordpress users to install/upgrade plugins, burning wordpress in a Docker image is not gonna work: either you allow the app to be updated only by distributing a new docker image or you don't. What you want to do allows for app updates to come from two sources.

If you don't have such requirement, just add:

define(‘DISALLOW_FILE_MODS’,true);

to wp-config.php and you are good to go. Make sure that when you upgrade your Docker image with a new version of Wordpress, the database schema is upgraded accordingly and all versions of Wordpress currently in execution can use that db schema.

If you can't disable plugin installation/updates, you need to solve 2 problems:

1) You need to have all containers access the same wordpress installation.

On-disk files in a container are ephemeral, which means when a container crashes, kubelet will restart it, but the files will be lost - everytime you get a clean slate.

A typical solution to this problem is to create a volume just to store your wordpress installation and mount it on all containers in the Pod, like this:

volumes:
  - name: wp-webroot
    emptyDir: {}

- name: wp-container
    image: wp
    volumeMounts:
    - name: wp-webroot
      mountPath: /var/www/html

- name: wp-container2
    image: wp
    volumeMounts:
    - name: wp-webroot
      mountPath: /var/www/html

More info:

https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/

2) You need to make the storage of the shared volume reliable/redundant. Kubernetes offers many options that vary depending on where you are running your Kubernetes installation. If you are in a public cloud use whatever that cloud makes available (e.g. EFS on AWS), if you are on-premise you might want to look into glusterfs or if you have an existing SAN use that.

More info on: https://kubernetes.io/docs/concepts/storage/volumes/

Regarding your request for some bibliography on the topic, you will find many documents telling you that your application should be part of the image, e.g. point #7 in:

https://developers.redhat.com/blog/2016/02/24/10-things-to-avoid-in-docker-containers/

but again, that assumes that the application can only be upgraded/modified by the admin, not the end users. You must contextualize the suggestions that you find on the web to your specific requirements.

Luca Gibelli
  • 2,611
  • 1
  • 21
  • 29
  • Thanks, but I could also share the same code across the pods by building a wordpress image that includes the source. This would mean I have an image which represents my app all by itself. It feels like I'm _forced_ to use a `PersistentVolume` only because in typical WP deployments users may expect to be able to add themes & plugins via the admin. Do you see what I mean? Is there a discussion somewhere about incorporating application code into an image? It feels very natural in that you can version images with tags, but causes problems with wordpress because you can add code through the app... – quickshiftin Apr 18 '18 at 12:35
  • The problem with that approach is that it requires a restart of the containers to deploy a new version, normally you don't want to do that. Also you don't want multiple versions of the same app running at the same time, so you would have to kill them all, wait for them to terminate, then start the new version. – Luca Gibelli Apr 18 '18 at 13:55
  • Neither of those statements are true. One of the main goals of a Deployment is to facilitate a [rolling update](https://kubernetes.io/docs/tasks/run-application/rolling-update-replication-controller/). So you introduce the new version of the app incrementally. – quickshiftin Apr 18 '18 at 14:05
  • Those statements are not true ***in general***, but they are true in your specific case: wordpress. Different versions of wordpress may require a DB upgrade. If you run different versions of wordpress backed by the same db, some instances will stop working. If you use different dbs then you introduce a desync problem – Luca Gibelli Apr 18 '18 at 16:05
  • updated answer to clarify that my suggestion stems from the need to allow users to install/upgrade plugins – Luca Gibelli Apr 18 '18 at 16:29
  • Thanks, answer accepted! I especially like the `DISALLOW_FILE_MODS` tip. Do you know where there are some articles discussing 'burning' the application source into an image? I'd like to do this for some _non-wordpress_ applications, but unsure what to google for... – quickshiftin Apr 18 '18 at 17:08
  • you're welcome! I posted one link at the end of the answer. You can find more by googling 'ship application with docker image' and similar keywords – Luca Gibelli Apr 18 '18 at 17:31