How to deploy WordPress in Kubernetes
This guide describes how to deploy a scalable WordPress application inside a Kubernetes cluster based on Virtuozzo Infrastructure.
A typical simple WordPress application consists of the following components:
- The WordPress server that stores website content.
- The MySQL server that stores users and configurations.
- A load balancer that routes traffic from a public network to the WordPress server or servers.
To provide high availability for your website or the ability to scale it according to the external load, we will deploy multiple WordPress servers. In a real-life scenario, you should also have multiple MySQL servers with the active-active or active-passive configuration, which is out of scope of this guide. You can find a lot of examples of highly available MySQL clusters for Kubernetes on the Internet.
The schema of our WordPress deployment looks as follows:

Prerequisites
1. Deploy a Virtuozzo Infrastructure cluster.
2. Create the compute cluster with the Kubernetes service.
3. Configure the default storage policy for boot volumes on Kubernetes master nodes. Ensure that the selected policy is available for all projects where you are planning to deploy Kubernetes.
4. Install kubectl on your workstation.
5. Install Helm on your workstation.
6. Download and install Lens on your workstation.
7. Download the following WordPress deployment files:
8. In Virtuozzo Infrastructure, create a demo project with enough quotas to run a Kubernetes cluster. In your project, create a virtual network, a virtual router, and upload an SSH key:
For the network, specify the following parameters:
- Name:
private - IPv4 subnet:
10.0.0.0/24 - Gateway:
10.0.0.1 - DNS server:
8.8.8.8
- Name:
For the router, specify the following parameters:
- Name:
router - The router connects your private and public networks
- Name:
9. Download the ISO image of the TrueNAS server and upload it to your project.
Preparing the demo environment
Deploying the NFS server
The WordPress server itself does not support native scalability. With multiple WordPress servers, these servers must have access to the same persistent volumes (PV) where the WordPress server stores its content. To have simultaneous access from multiple Kubernetes pods to the same PV, this PV must support the ReadWriteMany (RWX) access mode. As the Virtuozzo Storage driver for Kubernetes does not support RWX, we need to use an external storage, such as NFS. For more details, refer to the Kubernetes CSI Storage Developer Documentation.
For this environment, we will deploy a virtual instance of the TrueNAS server inside a virtual machine.
1. Open the Virtuozzo Infrastructure self-service panel, go to the Virtual machines screen, and click Create virtual machine. Specify the following parameters:
Name:
nas01Image:
<truenas-iso-image>Volumes:
- 100 GiB boot volume
- 200 GiB data volume
Flavor:
large(4 vCPUs, 8 GiB of RAM)Network interface:
private
2. Go to the Floating IPs screen and click Add floating IP. Select your public network to pick a floating IP from and assign this IP address to your nas01 private IP address.
3. Go to the nas01 virtual console and configure the TrueNAS server.
4. Go to the nas01 management IP address and log in to the interface.
5. Go to Services, enable the NFS service, and configure the following settings:
- Enable NFSv4:
enabled - NFSv3 ownership model for NFSv4:
enabled - Allow non-root mount:
enabled - Other settings:
disabled
6. Go to Storage → Pools, click Add, and specify the following parameters:
- Name:
pool1 - Select your 200 GiB disk
- Policy:
stripe
7. Go to Storage → Pools → pool1, click Add Dataset, and create a dataset with the name share1. Keep all other options by default.
8. Go to Sharing → Unix Shares (NFS), click Add, and specify the following parameters:
Path:
/mnt/pool1/share1General options:
- All dirs:
enabled - Quiet:
disabled - Enabled:
enabled
- All dirs:
Advanced options:
- Read only:
disabled - Maproot User:
non - Maproot Group:
non - Mapall User:
root - Mapall Group:
wheel
- Read only:
9. Test the NFS share by mounting it to your workstation. For MacOS, for example, you can mount it as follows:
| |
10. (Optional) As soon as you configure your NFS server, we recommend limiting access to it from the Internet. With the recommended security group, you will be able to access the NFS server management UI, while the NFS server itself will only be accessible from your private network. Configure the security policy as follows:
Inbound rules:
- Any: from your private IP range only
- HTTPS: only from your own public IP
Outbound rules: keep the default rules

Creating a Kubernetes cluster
1. Open the Virtuozzo Infrastructure self-service panel.
2. Go to the Kubernetes screen, and click Create Kubernetes cluster.
3. Specify the following parameters:
- Kubernetes version: the latest version
- Cluster name:
cluster01 - SSH key: your uploaded SSH key
- Network:
private - Floating IP address:
For Kubernetes API - High availability:
enabled(it will create three master nodes in the HA configuration) - Master node flavor:
mediumor any other flavor with at least 2 vCPUs and 4 GiB of RAM - Integrated monitoring:
enabled - Number of workers:
3 - Worker node flavor:
small - Other settings: keep the default values
4. Click Create.
Accessing the Kubernetes cluster
1. Once the status of your cluster01 Kubernetes cluster becomes Active, open its right panel and click Download kubeconfig to download the configuration file to your local machine.
2. On your local machine, open the terminal and load the kubectl configuration file:
| |
3. View the list of nodes in your Kubernetes cluster:
| |
4. Connect Lens to your Kubernetes cluster:
4.1. Open Lens and add a new Kubernetes cluster by adding your kubeconfig file.
4.2. Open the new Kubernetes cluster to review its components.
4.3. As the Kubernetes cluster has integrated monitoring enabled, you can also view the load for your master and worker nodes, as well as other helpful usage statistics provided by the integrated Prometheus server.
5. Create a storage class that allows creating persistent volumes automatically. PVs will be based on OpenStack Cinder and the underlying storage policy, and we will use the default storage class to create them for the MySQL server.
| |
Deploying NFS subdir external provisioner
We use NFS subdir external provisioner to automatically manage NFS-based persistent volumes for Kubernetes. The detailed description is also available on the GitHub page.
To deploy NFS subdir external provisioner, run the following command in your terminal:
| |
Where:
nfs.serveris the private IP address of your NFS server.nfs.pathspecifies the full path to your NFS share. If you configured TrueNAS according to this guide, the path will be/mnt/pool1/share1.storageClass.accessModesis the PV access policy. In our case, it isReadWriteMany. =storageClass.namesets the name for the new storage class based on NFS. In our case, it isnfs.
You can check that the new storage class is successfully created by running:
| |
Running the demo
Deploying a WordPress application
During the preparation stage, we have created two storage classes:
| |
The default storage class is based on Virtuozzo Storage, and the nfs one is based on the external NFS server with RWX persistent volumes support.
Now, we can deploy a WordPress application (refer to the Prerequisites section, to download the required deployment files).
1. Use the kustomization.yaml file that does the following:
1.1. Creates a secret with a password for the MySQL database. You can change the default password in the parameter password=Virtuozzo1.
1.2. Creates the MySQL service and a pod by running the mysql-deployment.yaml file.
1.3. Creates the WordPress service and pods by running the wordpress-deployment-nfs.yaml file.
2. Run the command:
| |
3. To check the deployed components, use these commands:
| |
4. To get the public IP address of your WordPress, run:
| |
In this example, your public IP address is 23.109.29.208. This is the floating IP that is assigned to the load balancer created specifically for this WordPress application in your Virtuozzo Infrastructure project.
Now, you can open this IP address in your browser to access your WordPress website. To review the WordPress components, you can also use Lens.
Testing WordPress availability and scalability
For high availability and the ability to scale our deployment, we have deployed three replicas of the WordPress server:
| |
1. Open the Virtuozzo Infrastructure self-service panel, go to the Virtual machines screen, and find the Kubernetes worker node with a name similar to <cluster01-mxtbkucksr3w-node-0>. Stop the VM by clicking Power off.
2. To check the status of our pods, list them by running:
| |
You can see that one of our pods has just been restarted. This happens because Kubernetes automatically supports the required number of pods and creates a new pod if one of them was lost due to worker node issues. The WordPress website is still available.
3. To add more WordPress servers to support the growing workload on our website, we need to change the number of replicas by running:
| |
4. Check the number of pods by listing them:
| |
Now, we have five WordPress pods running.
You can also scale WordPress by changing the number of replicas in the WordPress deployment file and re-running it:
1. Open wordpress-deployment-nfs.yaml.
2. Change the replicas parameter from 3 to 5 or vice versa.
3. Run the command:
| |
If you have any issues with pods, you can use the following command for troubleshooting:
| |
(Optional) Deploying WordPress with Helm and Bitnami
Helm allows you to deploy WordPress with a fully highly available and scalable configuration in a single click by using the Bitnami WordPress template. The detailed description is also available on the GitHub page.

Before you proceed, ensure that you have the following:
- Helm is installed.
- NFS provisioner is configured with the storage class named
nfs.
To deploy WordPress with Helm:
1. Adapt the WordPress configuration file according to your requirements. To create the default file, run:
| |
The file will be created in your local directory. Please inspect it. If you have the default configuration created based on this guide, you can download the example configuration file or use wget:
| |
The example file has the following additional settings:
- Storage policy for persistent volumes:
nfs - WordPress admin password:
Virtuozzo1! - WordPress app servers replication: enabled with
3replicas - MariaDB replication:
enabledwith the active-passive configuration - Memcached server:
enabled - Integrated metrics:
enabled
2. Run the command:
| |
Now, you can follow the onscreen guide to access your WordPress website:
| |
Enjoy!