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.
| 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 |
| allow-drupal-to-db | NetworkPolicy | - | Restricts MariaDB ingress to Drupal pods only |
| allow-drupal-to-redis | NetworkPolicy | - | Restricts Redis ingress to Drupal pods only |
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.
db-password value in drupal-secrets to a strong, unique password before deploying.host: field to the Ingress rule if serving Drupal on a specific domain.kubectl get pvc -n cms-web and confirm all four PVCs show status Bound.http://<your-cluster-ip>/ in a browser; the Drupal installation wizard should appear.kubectl exec -n cms-web drupal-db-0 -- mysqladmin ping -u root -p<password> to confirm MariaDB is healthy.kubectl exec -n cms-web redis-0 -- redis-cli ping and verify the response is PONG.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.