Deploying WordPress and MySQL on Kubernetes with Persistent Volumes

This tutorial shows you how to deploy a WordPress site and a MySQL database using Kubernetes. Both applications use PersistentVolumes and PersistentVolumeClaims to store data.

MySQL & Wordpress


  • Create PersistentVolumeClaims and PersistentVolumes
  • Create a Secret
  • Deploy MySQL
  • Deploy WordPress
  • Clean up

Before you begin

You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one for free on OCI here.

Creating a Kubernetes Cluster on OKE

You can choose Quick Create for creating your Kubernetes cluster if using OKE. This will create all prerequisite resources such as VCN and Subnets.

Create options OKE

You will then see the form for configuration is pre-filled for you:

OKE Setup

Once you have your cluster created you can download your Kubeconfig file and access your cluster through Kubectl CLI.

Intro to PersistentVolumeClaims and PersistentVolumes in Kubernetes

A Persistent Volume is some storage in the cluster that has been manually provisioned by an administrator, or dynamically provisioned by Kubernetes using a StorageClass.

A Persistent Volume Claim is a storage request by a user that can be fulfilled by a PV.

PersistentVolumes and PersistentVolumeClaims are independent of Pod lifecycles and preserve data through restarting, rescheduling, and even deleting Pods***.

***Note: If testing this locally with Minikube and local clusters, the default StorageClass will use thehostPath. hostPath volumes are only suitable for development and testing and you will not be able to migrate this easily to production. With hostPath volumes, your data is kept in the/tmp folder of the node. Meaning if a Pod is killed, dies, gets scheduled to another node in the cluster, or the node is rebooted, the data is lost.

Therefore if you are bringing up a cluster that needs to use them hostPath provisioner, the --enable-hostpath-provisioner the flag must be set in the controller-manager component.

Creating PersistentVolumeClaims and PersistentVolumes on Kubernetes

Both MySQL and Wordpress require a PersistentVolume to store data. We will see the PersistentVolumeClaims be created when we get to the deployment step.

When a PersistentVolumeClaim is created, a PersistentVolume is dynamically provisioned based on the StorageClass configuration as we are using Kubernetes.

Most cluster environments will have a StorageClass created by default. This can be useful when a StorageClass is not specified in the PersistentVolumeClaim because the cluster will default back to the default StorageClass.

Create a Secret for MySQL Password

A Secret is an object that stores a piece of sensitive data like a password or key. Each item in a secret must be base64 encoded. Let’s create a secret for admin use. Encode the password (in my case — mysql-pass):

$ echo -n 'mysql-pass' | base64

This can be added to the Kubernetes kustomization.yaml

kustomize, is a template-free configuration customization for Kubernetes. It is a command line tool that provides a new, purely declarative approach to configuration customization that adheres to and leverages the familiar and carefully designed Kubernetes API.

The kustomization.yaml file is itself a manifest, which specifies a list of resources, patches to apply, and various other options. You will need one of these and a Kubernetes manifest file/ resource configs to use Kustomize.

Adding Secret to kustomization.yaml

You can add the password to the secret generator in the kustomization.yaml file as shown below:

cat <<EOF >./kustomization.yaml
- name: mysql-pass
- password=***YOUR_PASSWORD***

Add resource configs for MySQL and WordPress

As mentioned to use Kustomise will need to Kubernetes Manifest files or resource configs.

We can download the configuration files for Wordpress and MySQL which have been created by

Download the MySQL deployment configuration file.

curl -LO

Download the WordPress configuration file.

curl -LO

Add them to kustomization.yaml

We can now add them to the Add them to kustomization.yaml file. as seen below:

cat <<EOF >>./kustomization.yaml
- mysql-deployment.yaml
- wordpress-deployment.yaml

Time to Test, Apply and Verify

The kustomization.yaml contains all the resources for deploying a WordPress site and a MySQL database. You can apply the directory by

kubectl apply -k ./

You can now verify if your services are set up correctly:

We will firstly check the pods are running (note this can take a few minutes to leave it run for a few minutes).

You can check pods by running:

kubectl get pods

You should get output such as:

NAME                               READY     STATUS    RESTARTS  AGE
wordpress-mysql-7341782511-c3bjd 1/1 Running 0 4m

This verifies that our MySQL service is running on a pod.

We will then verify if the Wordpress service is running.

This can be checked by:

kubectl get services wordpress

You should get an output such as:

wordpress ClusterIP 80:32406/TCP 9m

Test Wordpress

Now that your service is up and running you can test Wordpress using the external IP. You can choose your language and then set up your site and password.

Note that you will not need to create a Database connection as is normally required to be done in Wordpress as MySQL has been pre-configured in the wordpress-deployment.yaml file.

Now that you have Wordpress configured you can start creating a site for yourself.

What can I do now:

Now that you have Wordpress configured you can start creating a site for yourself using MySQL as a Database.

As use cases and sites will be different for everyone so please consult the Wordpress & MySQL documentation, or feel free to reach out with any questions!

Any questions:

For more information please feel free to reach out on LinkedIn or Twitter