Deploy Drupal + MariaDB + Redis on Kubernetes: Production-Ready CMS
Running Drupal on Kubernetes requires coordinating a stateful database, a cache layer, and a web application tier with shared persistent storage. This template deploys Drupal 10 with MariaDB in a StatefulSet and Redis for page and object caching on any NGINX-ingress-enabled cluster. The result is a scalable CMS stack with health probes, resource limits, and network policies configured out of the box.
What's Included
| Component | Type | Port | Role |
|---|---|---|---|
| drupal-app | Deployment | 80 | Serves Drupal 10 over Apache; mounts shared files PVC |
| drupal-db | StatefulSet | 3306 | MariaDB 10.11; one PVC per replica via volumeClaimTemplates |
| redis | StatefulSet | 6379 | Redis 7 cache layer for Drupal page and object cache |
| drupal-service | Service (ClusterIP) | 80 | Internal service fronting the Drupal Deployment |
| db-service | Service (Headless) | 3306 | Headless service enabling per-pod DNS for MariaDB replicas |
| redis-service | Service (Headless) | 6379 | Headless service enabling per-pod DNS for Redis replicas |
| drupal-ingress | Ingress | 80 | Routes external HTTP traffic to drupal-service via NGINX |
| drupal-hpa | HorizontalPodAutoscaler | - | Scales Drupal pods between 2 and 5 replicas at 70% CPU |
| drupal-secrets | Secret | - | Holds MariaDB root and Drupal user passwords |
| cms-ssd-storage | StorageClass | - | Local-path storage class; swap for cloud CSI in production |
| pvc-drupal-app | PersistentVolumeClaim | - | ReadWriteMany volume shared across all Drupal pods |
| allow-drupal-to-db | NetworkPolicy | - | Restricts MariaDB ingress to Drupal pods only |
| allow-drupal-to-redis | NetworkPolicy | - | Restricts Redis ingress to Drupal pods only |
Architecture Overview
External HTTP traffic enters through the NGINX Ingress and reaches drupal-service, which load-balances across Drupal pods. Each pod connects to MariaDB via headless db-service using per-pod DNS and to Redis via redis-service for caching. All Drupal replicas share a ReadWriteMany PVC for sites/default/files. NetworkPolicies enforce that only Drupal pods can reach the database and cache tiers. The HPA scales the Deployment based on CPU utilization.
Prerequisites
- A running Kubernetes cluster (Docker Desktop, Minikube, or any cluster)
- NGINX Ingress Controller installed on the cluster
- At least 6 GB of node memory allocated
- Host paths
/mnt/data/db-0,/mnt/data/db-1,/mnt/data/db-2,/mnt/data/app-contentcreated on the node (local clusters only; use cloud CSI PVs in production) - KubeKanvas CLI installed and running on your computer (Optional, if you want to use one-click deployment)
How to Deploy
- Update the
db-passwordvalue indrupal-secretsto a strong, unique password before deploying. - For local clusters, verify the four host paths exist on your node. For cloud clusters, replace
hostPathPV definitions with your CSI equivalents and update the StorageClass provisioner. - Confirm NGINX Ingress Controller is running. Add a
host:field to the Ingress rule if serving Drupal on a specific domain. - Deploy the template to your cluster via the Play button in the top right bar. If you prefer to deploy manually, download the YAML and apply it with kubectl.
- Wait for all pods to reach Running status. You can monitor progress in the Release Monitor screen.
How to Test
- Run
kubectl get pvc -n cms-weband confirm all four PVCs show statusBound. - Open
http://<your-cluster-ip>/in a browser; the Drupal installation wizard should appear. - Run
kubectl exec -n cms-web drupal-db-0 -- mysqladmin ping -u root -p<password>to confirm MariaDB is healthy. - Run
kubectl exec -n cms-web redis-0 -- redis-cli pingand verify the response isPONG.
Use Cases
- Multi-replica CMS: Run Drupal with 2-5 replicas sharing a common files directory via a ReadWriteMany volume.
- Stateful database on Kubernetes: Use MariaDB in a StatefulSet with per-pod PVCs for stable network identities and individual disk persistence.
- Cache-backed Drupal: Connect Drupal's page and object cache modules to Redis to offload PHP processing on high-read workloads.
- Network-isolated stack: Enforce that only application pods reach the database and cache tiers using NetworkPolicy without an external firewall.
- Autoscaling web tier: Pair a fixed StatefulSet database with an autoscaling Deployment for variable PHP traffic.
Summary
This template configures a three-tier Drupal CMS stack with a 3-replica MariaDB StatefulSet,
a 3-replica Redis StatefulSet, and an autoscaling Drupal Deployment, including persistent
storage, health probes, resource limits, NetworkPolicies, and NGINX Ingress routing in the
cms-web namespace.
