How to Deploy WordPress Instance on Kubernetes

September 2, 2021

Introduction

As the most popular content management system globally, WordPress runs websites of various sizes, both in terms of the amount of content and web traffic. Deploying WordPress on Kubernetes is an efficient way to enable horizontal scaling of a website and successfully handle website traffic surges.

This tutorial explains two methods of deploying WordPress on Kubernetes - using Helm charts and creating your deployment from scratch.

How to Deploy a WordPress Instance on Kubernetes

Prerequisites

  • A Kubernetes cluster with kubectl
  • Helm 3
  • Administrative privileges on the system

Deploying WordPress on Kubernetes with a Helm Chart

Helm charts come with pre-configured app installations that can be deployed with a few simple commands.

  1. Add the repository containing the WordPress Helm chart you want to deploy:
helm repo add [repo-name] [repo-address]

The system confirms the successful addition of the repository. The example uses the Bitnami chart.

Adding the Bitnami Helm chart repository

2. Update local Helm repositories:

helm repo update
Updating Helm repos

3. Install the chart using the helm install command.

helm install [release-name] [repo-address]

Wait for the chart to be deployed.

Installing the bitnami WordPress helm chart

4. The WordPress service uses LoadBalancer as a way to expose the service. If you are using minikube, open another terminal window and type the following command to emulate the LoadBalancer:

minikube tunnel

5. When minikube displays the Running status, minimize the window and return to the previous one.

Using the minikube tunnel command to provide load balancing

6. Check the readiness of the deployment by typing:

kubectl get all

The command lists and shows status of the pods, services, and deployments.

Checking the readiness of pods, services, and deployments

7. Once the pods and the deployment are ready, use the following command to export the SERVICE_IP environment variable:

export SERVICE_IP=$(kubectl get svc --namespace default wp-test-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")

8. Now use the echo command to display the IP address of the service:

echo "WordPress URL: http://$SERVICE_IP/"
Obtaining the WordPress service IP address

9. Type the address into the address bar of your browser. The WordPress installation starts.

Deploying WordPress on Kubernetes with Persistent Volumes

When deploying WordPress using a custom configuration, you need to create a series of YAML files for WordPress and the database the app will be using. The example below uses MySQL, but you can also opt for MariaDB.

1. Use a text editor to create the YAML file to provision storage for the MySQL database.

nano mysql-storage.yaml

The file defines a persistent storage volume (PV) and claims that storage with the PersistentVolumeClaim (PVC). The example uses the following configuration:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Save the file and exit.

2. Create the MySQL deployment configuration YAML.

nano mysql-deployment.yaml

The deployment file contains the data related to the container image and the storage. The claimName declaration at the bottom should correspond to the name of the PVC you created in Step 1.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:5.7
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim

Save the file and exit.

Note: Learn how to deploy a MySQL database instance on Kubernetes using persistent volumes.

3. Create the service configuration YAML for the database.

nano mysql-service.yaml

The file specifies the port that WordPress uses to connect to the service:

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None

Save the file and exit.

4. Now create the same YAML files for WordPress itself. Start with the storage allocation:

nano wordpress-storage.yaml

The example uses the following configuration:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: wp-pv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Save the file and exit.

5. Create the deployment file:

nano wordpress-deployment.yaml

The file provides the Docker image and connects the WordPress deployment with the PVC:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:5.8-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim

Save the file and exit.

6. Create the service YAML:

nano wordpress-service.yaml

The example uses LoadBalancer to expose the service:

apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer

Save the file and exit.

7. Create the kustomization.yaml file, which will be used to apply the configuration easily:

nano kustomization.yaml

The file contains two parts:

  • secretGenerator produces the Kubernetes secret that passes the login info to the containers.
  • resources section lists all the files that will participate in configuration. List the files you created in previous steps.
secretGenerator:
- name: mysql-pass
  literals:
  - password=test123
resources:
  - mysql-storage.yaml
  - mysql-deployment.yaml
  - mysql-service.yaml
  - wordpress-storage.yaml
  - wordpress-deployment.yaml
  - wordpress-service.yaml

Save the file and exit.

8. Apply the files listed in kustomization.yaml with the following command:

kubectl apply -k ./

The system confirms the successful creation of the secret, services, PVs, PVCs, and deployments:

Using Kustomize to apply the deployment configuration

9. Check if the pods and the deployments are ready:

kubectl get all
Checking the readiness of pods, deployments, and services

10. If you use minikube, open another terminal window and start minikube tunnel to provide load balancing emulation:

minikube tunnel

Once the emulation is running, minimize the window and return to the previous one.

11. Type the following command to expose the service URL that you will use to access the deployed WordPress instance:

minikube service wordpress-service --url

The URL is displayed as the command output:

Obtaining the url for connecting to WordPress service

Note: If you do not use minikube, use the external IP address and the port of the WordPress service from the table in Step 9.

12. Copy the URL and paste it into your web browser. The WordPress installation starts.

The installation windows of WordPress

Conclusion

After reading this tutorial, you will learn two methods for deploying a WordPress instance on Kubernetes. If you want to know more about managing WordPress, read 25 Performance and Optimization Tips to Speed Up Your WordPress.

Was this article helpful?
YesNo
Marko Aleksic
Marko Aleksić is a Technical Writer at phoenixNAP. His innate curiosity regarding all things IT, combined with over a decade long background in writing, teaching and working in IT-related fields, led him to technical writing, where he has an opportunity to employ his skills and make technology less daunting to everyone.
Next you should read
How to Install WordPress Manually Using cPanel
July 31, 2018

WordPress (WP) is a widely used content-management system. Its ease of use, numerous themes, plugins, and strong community support, have made it the number one solution in the world. This tutorial will show...
Read more
20 Best WordPress Security Plugins to Lock Out Hackers
September 2, 2021

Your WordPress website is an extension of your business, or in some cases, your entire business. Much like you would protect an office building from potential threats, you should be taking on the same responsibility...
Read more
How to Create & Edit the Default WordPress .htaccess File
May 22, 2019

The .htaccess file can enable or disable many server features, including redirection of URLs, server signature, caching of files, and password protection. This tutorial will show you how to find, edit, and create...
Read more
How to Fix the 500 Internal Server Error in WordPress
May 28, 2019

The 500 Internal Server Error is one of the most common WordPress errors. This article will show what steps to take to identify the cause of the error. In addition, we will provide an in-depth analysis of the most effective...
Read more