You probably think it’s overkill to use Kubernetes for a WordPress blog with less than a thousand monthly visitors. While this may be true, it’s totally worth using Kubernetes for the bragging rights. This is a WordPress blog running on Kubernetes!
Hardware
Hosting is provided by Heart Internet. Fortunately, the instance has 2 vCPUs (minimum required by some Kubernetes distributions), 8 GB memory and 100GB NVMe SSD storage. The virtual machine runs CentOS 7.
Kubernetes Distribution
minikube is the distribution choice because of its popularity and ease of use. See our article on Kubernetes distributions for local environments for other options.
Driver choice
minikube offers a variety of drivers to choose from. This server uses the “none” driver for an advanced configuration using docker.
Start minikube on boot
minikube is in the startup so systemd will ensure it is started on every boot. To achieve that, save the following file to /etc/systemd/system/minikube.service:
Note: You’ll need to replace “jsmith” with the user that set up minikube since minikube will need to access “.minikube” directory in the user’s home directory
Once that’s done, run the following command to reload systemctl configuration:
systemctl daemon-reload
To finish adding minikube to startup and to start and stop minikube you can now use these commands:
# Add to startup systemctl enable minikube.service # Stop systemctl stop minikube.service # Start systemctl start minikube.service
MariaDB Database
Choose MariaDB but not because Sun Microsystems owns MySQL, do it because MySQL core developers have joined the MariaDB team. As a result, MariaDB is more performant and has a lot more features than MySQL. See this blog post comparing MySQL, MariaDB and Percona for WordPress by Kernl.us.
Root password secret
To install MariaDB into our cluster we first need to ensure we have the secret required for the deployment:
kubectl create secret generic radwell-blog-mariadb \ --from-literal=root-password=supersecurepassword
Persistent storage
As you can see in the PersistentVolume resource definition, MariaDB data is on the host disk (hostPath storage) in the “/data/radwell-blog-database” directory. For this reason, this storage setup only works for single-node clusters.
Kubernetes resources
Below are the resources required for MariaDB:
Apply the resources above in the following order:
- backend-pv.yaml
- backend-pvc.yaml
- backend-deployment.yaml
- backend-service.yaml
NGINX + PHP-FPM
WordPress runs on PHP and since its static files are not separate it’s best to use NGINX rather than Apache. This is because NGINX performs better with static files. The difference between the solutions is negligible when a CDN is used to serve static files.
NGINX configuration
There are some things to note with our NGINX configuration. First of all, we’re redirecting the logs to the output so we can read them using kubectl log. We’re also enabling gzip compression and caching for performance. Finally, we’re configuring PHP files to use php-fpm.
Persistent storage
WordPress needs persistent storage for uploaded images and background updates. Like MariaDB, we’re using the host disk and storing files in the /data/radwell-blog-code directory.
To get WordPress running you’ll need to download WordPress and install it into the /data/radwell-blog-code directory on the host filesystem. Also, remember to configure the database to connect to the “radwell-blog-db” service we defined earlier.
Application container image
As you may know, Docker Hub has a container image for WordPress. That container image may not be for everyone because the image contains a single version of WordPress and doesn’t work for background updates. We’re using a php-fpm image with some additional PHP modules instead. Using the Dockerfile below, build and tag oradwell/blog. Alternatively, you can build the image directly from the gist URL.
docker build https://gist.githubusercontent.com/oradwell/af975a58a47eca39402a26c5d97d5724/raw/b44a1c72532bf9ef016033bc1f8c5429e93bf5e6/Dockerfile -t oradwell/blog
Kubernetes resources
Below are the resources required for the WordPress application itself:
Apply the resources above in the following order:
- code-pv.yaml
- code-pvc.yaml
- nginx-configmap.yaml
- frontend-deployment.yaml
- frontend-service.yaml
Ingress
To make the WordPress application accessible from outside the virtual machine we need to use an ingress.
Ensure ingress-nginx controller is enabled. You can do this with minikube using the following command:
minikube addons enable ingress
Now, all you need to do is to create the ingress resource.
Once the ingress is up, you should be able to access WordPress on port 80.
Last words
Since Kubernetes uses a lot of resources, it can only run on large machines and reduces the resources available for the services. That said, Kubernetes ensures the services are responsive by using probes. Therefore, it may be beneficial even for single-node environments. Do you think it is worth having a WordPress blog running on Kubernetes?
I’m planning on ditching Plesk for Kubernetes as I’m tired of Plesk’s handholding and limited backup options. Fascinating to see your process here.