Self-Host Strapi on Kubernetes
Strapi is an open source headless CMS: model content, expose it over REST and GraphQL, manage media from an admin panel. Self-hosting it on Kubernetes has two details that catch people out, which are how content types are deployed and where uploads live. This page covers both, plus the resource footprint. Edka deploys it on a cluster in your own cloud account.
What Strapi Needs to Run
- PostgreSQL. Strapi defaults to SQLite, which cannot survive a pod moving nodes. Edka connects it to an existing PostgreSQL installation on your cluster.
- A persistent volume for uploads, mounted at
/opt/app/public/uploads, so media survives restarts and redeploys. - Stable secrets. App keys, API token salt, admin and user JWT secrets, transfer token salt, and an encryption key. If these rotate, existing sessions and tokens break. Edka generates them once and keeps them stable for the lifetime of the instance.
Your Content Types Live in Your Image
This is the part that surprises people arriving from a CMS that keeps its schema in the database. In Strapi, content types are code, not rows. Creating a collection type in the admin panel writes schema files into the project on disk.
That works in development, where Strapi rebuilds on the fly. In production it does not: the container filesystem is not where you want your schema, and the admin panel is read only for content type editing when NODE_ENV=production.
The workflow is:
- Model your content types locally against the Strapi project.
- Commit the generated schema files.
- Build a container image from your project.
- Point the Edka deployment at that image.
Edka starts you on a starter image so you have a running admin panel immediately. Swap it for your own project image once you add custom content types or plugins. Content entries, users, and media stay in PostgreSQL and the uploads volume, so they carry across image updates.
Resource Requirements
| Setting | CPU | Memory |
|---|---|---|
| Request | 250m | 512Mi |
| Limit | 1000m | 1Gi |
Uploads storage defaults to 10 Gi and goes up to 1000 Gi. Strapi serves on port 1337.
Node builds are memory hungry, but that happens in CI rather than on the cluster if you build your image ahead of time. A CPX21 node (3 vCPU, 4GB) runs Strapi and leaves room. See the Hetzner instance types table.
One caveat on scaling: the uploads volume is a single ReadWriteOnce PersistentVolume, so the deployment runs one replica. Move media to an S3-compatible upload provider if you need several.
What Edka Provisions
- Strapi application. The Strapi server on port 1337, backed by a starter image you can swap for your own.
- PostgreSQL connection. An existing PostgreSQL installation, an empty database, and a login user. Edka resolves credentials from the cluster Secret.
- Generated secrets. App keys, API token salt, admin and user JWT secrets, transfer token salt, and encryption key, stored in a Kubernetes Secret and stable for the life of the instance.
- Persistent uploads. A volume mounted at
/opt/app/public/uploads.
Configuration Options
- Database. The PostgreSQL installation, database, and user. SSL settings carry over from the selected installation.
- Storage. Uploads volume size (default 10 Gi, up to 1000 Gi) and storage class, defaulting to
hcloud-volumes. - Resources. CPU and memory requests and limits.
- Placement. Pin Strapi to a node pool, with automatic tolerations for node pool taints.
- Access. Expose Strapi through an Envoy Gateway traffic class on a public hostname, which also sets
PUBLIC_URL. Telemetry is disabled by default.
Keeping Strapi Up to Date
Enable auto-updates to let the Edka agent apply newer chart and image versions. Choose a policy (patch, minor, major, all, or a custom tag pattern) and a check interval from every 5 minutes to daily. Leave updates off to pin exact versions.
Deploy Strapi
- Click “Deploy Strapi” below.
- Select an existing PostgreSQL installation, database, and user.
- Set your uploads storage size and storage class.
- Choose a traffic class and hostname to expose Strapi publicly.
- Deploy, then open the admin panel to create your first admin user.
Deploy Strapi
Strapi
CMS
FreeCategory
Content Management
Run Strapi on your own Kubernetes cluster with PostgreSQL, persistent uploads, and generated secrets. Resource defaults and custom image setup explained.
Get started