How To Deploy WordPress on Kubernetes Cluster (AWS)

Fima Sultana
5 min readMay 1, 2022

WordPress is a free and open-source content management system (CMS). It is a web publishing software that allows you to create your own website or blog. Every organization requires a WordPress site due to its popularity and SEO-friendly behaviour, but there is also the hassle of deploying the WordPress site in production. We, like many other organization, recently felt compelled to use WordPress for some of our blog and product pages. Because our entire infrastructure is deployed on Kubernetes, we needed to configure the wordpress site on Kubernetes as well to avoid additional server maintenance for only some of our wordpress sites. So, in this article, I’ll take you through the steps which I took during deployment.

I will discuss the following topics in this article:

  1. Create a PVC YAML file.
  2. Create a Deployment YAML file.
  3. Create a Svc YAML file.
  4. Create an Ingress YAML file.

So, let’s get started with the deployment. :)

PVC in K8s

A PersistentVolume (PV) is a piece of storage in the cluster that has been manually provisioned or dynamically provisioned using Storage Classes. Where a PVC is a declaration defining the request for storage data usage, which is mounted into a Pod for use. It is similar to a Pod. Pods consume node resources and PVCs consume PV resources. Persistent volumes exist beyond containers, pods, and nodes & Persistent volumes are long-term storage in Kubernetes cluster. Here we need to create PVC to mount wp-content data into the pods so whenever new pods come it doesn’t delete the plugins, themes and images. When Pods are replaced, the claimed volumes will be automatically mounted into the new Pods. Data will not be destroyed until the claim is deleted.

Here is the configuration file for the PVC (PersistentVolumeClaim):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-pvc
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

Deployment in K8s

A Kubernetes Deployment instructs Kubernetes on how to create or modify instances of the pods that contain a containerized application. Deployments can scale the number of replica pods, automatically replaces any instances that fail or become unresponsive , enable controlled rollout of updated code, or roll back to an earlier deployment version if necessary. Here We’re using rolling update deployment, which replaces the existing version of pods with a new version, updating pods slowly one by one, without cluster downtime.

Here is the configuration file for the deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
-
env:
-
name: wordpress_DB_HOST
value: "your_db_endpoint:3306"
-
name: wordpress_DB_USER
value: your_db_user
-
name: wordpress_DB_PASSWORD
value: your_db_pass
-
name: wordpress_DB_NAME
value: your_db_name
-
name: wordpress_CONFIG_EXTRA
value: "define('FS_METHOD','direct');\n"
image: "wordpress:5.3.0"
name: wordpress
ports:
-
containerPort: 80
resources:
limits:
cpu: "2"
memory: 2Gi
requests:
cpu: 150m
memory: 200Mi
volumeMounts:
-
mountPath: /var/www/html/wp-content
name: wordpress
volumes:
- name: wordpress
persistentVolumeClaim:
claimName: wordpress-pvc

SVC in K8s

A Service routes traffic across a set of Pods. Services are the abstraction that allow pods to die and replicate in Kubernetes without impacting your application. When created, each Service is assigned a unique IP address (also called clusterIP).

Here is the configuration file for the Service:

apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
namespace: default
spec:
ports:
-
port: 80
targetPort: 80
selector:
app: wordpress
type: ClusterIP

Ingress in K8s

Ingress is a Kubernetes API object that provides routing rules for managing external users’ access to Kubernetes cluster services, typically via HTTPS/HTTP. Ingress let you set up external URLs, domain-based virtual hosts, SSL, and load balancing. A ClusterIP provides network connectivity within your cluster. It can’t normally be accessed from outside. so we need to create an ingress to access the wordpress site from outside.

Here is the configuration file for the ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
name: wordpress
namespace: default
spec:
rules:
-
host: yourdomain.com
http:
paths:
-
backend:
service:
name: wordpress-svc
port:
number: 80
path: /
pathType: Prefix

so here is the full configuration file:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-pvc
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
-
env:
-
name: wordpress_DB_HOST
value: "your_db_endpoint:3306"
-
name: wordpress_DB_USER
value: your_db_user
-
name: wordpress_DB_PASSWORD
value: your_db_pass
-
name: wordpress_DB_NAME
value: your_db_name
-
name: wordpress_CONFIG_EXTRA
value: "define('FS_METHOD','direct');\n"
image: "wordpress:5.3.0"
name: wordpress
ports:
-
containerPort: 80
resources:
limits:
cpu: "2"
memory: 2Gi
requests:
cpu: 150m
memory: 200Mi
volumeMounts:
-
mountPath: /var/www/html/wp-content
name: wordpress
volumes:
- name: wordpress
persistentVolumeClaim:
claimName: wordpress-pvc
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
namespace: default
spec:
ports:
-
port: 80
targetPort: 80
selector:
app: wordpress
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
name: wordpress
namespace: default
spec:
rules:
-
host: yourdomain.com
http:
paths:
-
backend:
service:
name: wordpress-svc
port:
number: 80
path: /
pathType: Prefix

Now save the yaml file as wordpress.yaml and run the command below. This command will create deployment, pvc, svc, and ingress resources all at once.

# create resource(s)
kubectl apply -f wordpress.yaml

Now please go to the domain you specified in Ingress and install WordPress.

NOTE: Since I’m using Amazon Aurora Serverless as my database for this wordpress site, so that I didn’t deploy MySQL in the cluster.

The following command will also display the resources.

# List all pods in the namespaces
kubectl get pods

# List all pvc's in the namespaces
kubectl get pvc

# List all deployments in the namespaces
kubectl get deployments
# List all services in the namespaces
kubectl get svc
# List all ingresses in the namespaces
kubectl get ingress

The following command will display the entire syntax of your yaml file.

# Get a pod's YAML
kubectl get pod my-pod -o yaml

# Get a pvc's YAML

kubectl get pvc wordpress-pvc -o yaml
# Get a deployment's YAML
kubectl get deployments wordpress -o yaml
# Get a svc's YAML
kubectl get svc wordpress-svc -o yaml
# Get a ingress's YAML
kubectl get ingress wordpress -o yaml

Conclusion: With the above manifest, you can now deploy as many WordPress sites as you want. Just tweak the manifest file and apply it to your cluster. I hope this article has been helpful in deploying WordPress on your Kubernetes cluster.

Thank you for taking the time to read this.

Fima Sultana
DevOps Engineer,
10 Minute School Ltd.

--

--