Running Directus in production requires coordinating a stateful database, persistent file storage, and network isolation. This template deploys Directus 11 backed by PostgreSQL 16 on Kubernetes, producing a namespace-isolated setup with ingress routing, resource quotas, and pod-level network policies.
What's Included
| Component | Type | Port | Role |
|---|---|---|---|
| directus | Deployment | 8055 | Runs the Directus CMS application |
| directus-postgres | StatefulSet | 5432 | Runs PostgreSQL 16 as the primary database |
| directus-postgres-headless | Service (Headless) | 5432 | Stable DNS for the StatefulSet |
| directus-service | Service (ClusterIP) | 8055 | Exposes Directus internally |
| directus-ingress | Ingress | 8055 | Routes external HTTP traffic to Directus |
| directus-config | ConfigMap | - | Non-sensitive Directus environment variables |
| postgres-config | ConfigMap | - | Non-sensitive PostgreSQL environment variables |
| directus-secret | Secret | - | DB password, admin credentials, cookie secret |
| postgres-secret | Secret | - | PostgreSQL superuser password |
| directus-uploads-pvc | PVC | - | Persists uploaded files across pod restarts |
| pg-storage | PVC | - | Persists PostgreSQL data |
| directus-quota | ResourceQuota | - | Namespace-level CPU and memory ceilings |
| directus-limits | LimitRange | - | Default resource requests per container |
| database-policy | NetworkPolicy | - | Restricts DB ingress to Directus pods only |
| engine-ingress-policy | NetworkPolicy | - | Restricts Directus ingress to port 8055 |
Architecture Overview
Directus connects to PostgreSQL through the headless service DNS (directus-postgres-headless). The nginx Ingress routes traffic on directus.local to the ClusterIP service on port 8055. NetworkPolicies enforce isolation: PostgreSQL only accepts connections from app: directus pods, and Directus only accepts inbound traffic on port 8055. File uploads are decoupled from the application pod via a dedicated PVC.
Prerequisites
- A running Kubernetes cluster (Docker Desktop or Minikube recommended)
- NGINX Ingress Controller installed in your cluster
hostpathStorageClass available (default on Docker Desktop and Minikube)directus.localadded to/etc/hostspointing to127.0.0.1- KubeKanvas CLI installed and running on your computer (Optional, if you want to use one-click deployment)
How to Deploy
- Open the Secrets and replace all placeholders: set
DB_PASSWORDandPOSTGRES_PASSWORDto the same strong password, setSECRETto a random 32-character string, and updateADMIN_EMAILandADMIN_PASSWORD. - Confirm
DB_HOSTisdirectus-postgres-headlessandDB_DATABASEmatchesPOSTGRES_DBacross both ConfigMaps. - Adjust
ResourceQuotaandLimitRangevalues to match your cluster capacity. - 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 pods -n directusand confirm both pods showRunningwith all containers ready. - Open
http://directus.localand sign in with the admin credentials from your Secret. - Run
curl http://directus.local/server/pingand confirm it returnspong. - Upload a file via the admin UI, delete and recreate the Directus pod, and confirm the file persists.
Use Cases
- Local CMS development: Run the full stack on Docker Desktop to develop API-driven frontends without a remote environment.
- Upgrade testing: The StatefulSet and volumeClaimTemplate let you test Directus version upgrades against a persistent database without data loss.
- Resource-constrained clusters: ResourceQuota and LimitRange make this suitable for shared clusters with namespace-level ceilings.
- File-heavy content workflows: The decoupled uploads PVC handles large media libraries independently of the application pod lifecycle.
Summary
This template configures a namespace-isolated Directus CMS deployment with a StatefulSet-backed PostgreSQL database, persistent storage for data and uploads, ingress routing, resource governance, and network-level access control.
