Drupal on Kubernetes

Drupal on Kubernetes works when the PHP pods stay stateless and files, database, cache and cron are designed as separate pieces. This page explains the build, the trade-offs and what to confirm before you commit.

On this page

Why teams run Drupal on Kubernetes and what it changes

If your organization already runs a container platform, or has a requirement for repeatable releases across environments, the question is how a stateful CMS fits into that model. Drupal on Kubernetes means stateless PHP containers, with files, database, cache and cron moved out of the pod. The web pods hold only code built at image build time, so any replica can serve any request. Uploaded files go to a shared file system or object storage, the database runs as a managed service or a separately operated cluster, Redis or Memcache holds the cache, and cron runs as a scheduled Kubernetes job rather than inside a web container. Each of those external dependencies needs an owner, a backup plan and a monitoring target before the first deployment.

The software cost is lower than many teams expect. Drupal core and contributed projects hosted on Drupal.org are licensed under GPL-2.0-or-later, and there is no paid edition of Drupal itself, so the budget goes to build, integration and operations work. Drupal 11 is the current major version. According to the Drupal core release schedule, Drupal 12 is scheduled for the week of December 7, 2026, and Drupal 10 reaches end of life on December 9, 2026. Confirm which version your site targets and the PHP version your base image provides before you choose a container image, because each Drupal release sets its own minimum PHP version on the Drupal.org PHP requirements page.

Plan for the upgrade cadence as part of the platform, not as an afterthought. Bugfix releases arrive on the first Wednesday of each month and security releases on the third Wednesday, according to the Drupal core release schedule, so your pipeline must be able to rebuild and roll out an image on short notice. Ask any partner to show how a security release becomes a new image, how database updates and configuration import run during a rolling deploy, and who approves the change. Those answers determine whether Kubernetes gives you repeatable releases or simply moves the manual work into YAML.

Which file, database and cache patterns fit which situations

Shared ReadWriteMany file storage mounts one volume into every PHP pod, so Drupal's sites/default/files directory behaves as it does on a traditional server. This fits teams that want the least change to core file handling, have contributed modules that write to local paths without an object storage adapter, or run on-premises where an NFS or distributed file system is already supported by operations. The trade-off is that the storage layer becomes a shared dependency: latency on file reads, locking behavior and capacity growth all affect every replica at once. Private files still need a path outside the web root and a clear backup target.

  • Access mode support: Confirm that the storage class offers ReadWriteMany and that the vendor documents its behavior under concurrent writes from many pods.
  • Performance under load: Ask how file metadata operations scale when image styles generate many small files.
  • Private file separation: Plan a separate volume or path for private files, with access controlled by Drupal rather than by network position.
  • Backup consistency: Confirm snapshot and restore procedures for the volume, and whether they can run without pausing cron.
  • Growth and quotas: Ask how capacity is expanded and whether expansion requires downtime.

Confirm the access mode, latency profile and restore procedure with the storage vendor before the design is fixed.

How to build a Drupal Kubernetes release pipeline

This sequence turns a Composer-built Drupal codebase into a repeatable Kubernetes release, where code, files, settings, database changes and scheduled jobs each have a defined home and a check that proves they work before traffic moves.

  1. Build a Composer-built container image

    The delivery team installs Drupal and its contributed modules through Composer from a locked composer.lock file, then builds one immutable image that contains only the code, vendor directory and web root. The image is built once per release, tagged with the commit or build identifier, and pushed to a registry you control. Confirm the build runs without network access to Drupal.org if your environment requires it. The step closes when the same image digest can be pulled and started in a test namespace with no database attached.

  2. Separate code, files and settings

    Keep the image free of uploaded files, private files and environment secrets. Public and private file directories are mounted from shared storage, while database credentials, hash salt and trusted host patterns are injected at runtime through Kubernetes Secrets and ConfigMaps and loaded from settings.php. Ask whoever owns the cluster how Secrets are encrypted at rest, since Kubernetes stores them unencrypted in etcd by default. The step closes when a pod started from the image reads its settings from the environment and writes uploads to the mounted path rather than the container filesystem.

  3. Provision storage and database services

    Platform engineers provision the database, cache service and file storage that the release depends on. Choose between a shared file volume that supports multiple writers or object storage through a Drupal module, and confirm the database engine and version meet the Drupal release you are running. Restore a copy of production data into a staging database to test the upgrade path. The step closes when Drupal can connect to the database from a pod, write a test file to the storage path, and a backup of the database has been taken and restored in a separate location.

  4. Deploy the web workload with readiness checks

    Deploy the Drupal web Deployment with a readiness probe that calls a lightweight route and fails until the database connection and file paths are working, plus a liveness probe with a looser threshold. Scale replicas only after the first pod passes. Run drush status inside a pod to confirm Drupal bootstraps, reports the expected database and file paths, and shows the correct release. The step closes when the service endpoint returns successfully and drush status reports a healthy bootstrap on each replica.

  5. Run database updates as a Job

    Before the new web pods receive traffic, run a Kubernetes Job from the same image that executes drush updatedb and then drush cache:rebuild. Use a rolling strategy that keeps the previous release compatible with the new schema for the rollout window, or plan a maintenance window if it is not. Confirm the Job exits with status zero and review its logs for each applied update hook. The step closes when the Job reports complete, the update log shows no pending hooks, and the new replicas pass readiness.

  6. Import configuration from version control

    Run drush config:import from the same release image as a Job or a controlled step after the database update. Configuration is exported to version control and imported into each environment, so the target environment matches the reviewed code. Check that the import reports no unexpected changes and that the active configuration matches the exported files. The step closes when drush config:status reports no differences and the import output is recorded with the release identifier.

  7. Schedule cron as a CronJob

    Move Drupal cron out of web pods into a Kubernetes CronJob that runs drush cron on a fixed schedule with the same image and settings. Set concurrency so overlapping runs cannot start, and set history limits so failed runs remain visible. Confirm the cron run is recorded in the job logs and that the scheduled tasks Drupal reports as last run have updated. The step closes when a manual trigger and at least one scheduled run complete successfully, and the logs show the cron execution with no errors.

How rolling deploys handle database updates and configuration import

The database updates and configuration import must run once per release, not once per pod. A Deployment that scales to several replicas starts each pod with the same image, so an entrypoint that runs drush updatedb or drush config:import on every start will race against its siblings, lock tables, and repeat work that only needs to happen one time. Move these steps into a Kubernetes Job (or a Helm or Argo CD hook that runs before the new Deployment rolls out), keep the web pods free of schema work, and make the Job fail the release if it does not finish cleanly. Confirm the exact Drush command sequence, including whether maintenance mode, cache rebuild and config import order differ, against the Drupal version in use, since the update path changes between major versions.

A rolling update can leave old and new code serving traffic at the same time, and that overlap is the main risk. While some pods run the previous release and others run the new one, the database may already contain columns, tables or config that the old code does not expect. Plan schema changes so they are backward compatible for one release: add new fields or tables first, deploy code that tolerates both states, and remove old structures in a later release. Pausing cron is part of the same discipline. Scheduled runs from a CronJob or a cron pod should be suspended or held in maintenance mode for the duration of the update, so cron does not execute queue workers or entity operations against a half-updated schema. Ask your team to document how cron is paused, resumed and verified in each environment.

Treat the Job, the rollout strategy and the pause or resume steps as one tested runbook. Rehearse the full sequence on a staging cluster with a copy of production data, and record how long the database update and config import take so the rollout window is known before launch. Check the release notes for each Drupal and contributed module upgrade, because update hooks can be long-running or require manual steps. Keep a database backup or snapshot taken immediately before the Job runs, so a failed update has a defined recovery path. Your implementation partner or internal team should own the decision on whether a rollback restores code only or code and database together, since rolling back code after a schema change can leave the site inconsistent.

Which Kubernetes security controls protect Drupal secrets and access

A Drupal site on Kubernetes holds database credentials, the hash salt, and API keys in Secrets, and its pods run code that accepts traffic from the internet. The controls below cover where those secrets rest, who can read them, how pods are allowed to run, and how security releases reach running containers.

Encrypt Secrets at rest in etcd

Kubernetes stores Secrets unencrypted in etcd by default, so anyone who can read the etcd data directory or its backups can read the database password and the Drupal hash salt. Ask your platform team whether the cluster has encryption at rest configured for Secrets, and confirm that etcd snapshots taken for backup are encrypted and access-controlled as well. Check the etcd backup files, not only the live cluster.

Restrict list and watch on Secrets

Reading a single Secret is not the only risk. Permissions to list and watch Secrets in a namespace can expose every value that the Drupal pods depend on at once. Bind the service accounts used by the Drupal deployment, cron jobs and migration jobs to narrowly scoped roles, and review who holds cluster-wide roles that include these verbs. Confirm that CI pipelines do not hold broader rights than the deploy step needs.

Pull external secrets with the CSI driver

Where the organization already runs a vault or cloud secrets manager, the Secrets Store CSI Driver can mount values from that external store into the pod, which keeps the source of truth outside the cluster. This suits the Drupal database credentials and API keys that rotate on a schedule. Confirm with your security team who owns rotation, how the pod reloads after a rotation, and whether the mounted values also land in etcd.

Enforce Pod Security Standards on PHP containers

Drupal containers need a writable file path for public and private files and a PHP runtime, but they rarely need root, host networking or privileged mode. Apply a Pod Security Standard level to the Drupal namespace, run containers as a non-root user, and drop unneeded Linux capabilities. Test the profile against your image before rollout, because a restrictive setting can block Drupal's writes to its file directories.

Rebuild images for Wednesday security releases

The Drupal Security Team publishes advisories and security releases on the third Wednesday of the month, and contributed module fixes arrive on the same windows. A patched Drupal codebase reaches the cluster only when the image is rebuilt and redeployed, so a Kubernetes rollout does not patch Drupal by itself. Agree in advance who watches the advisories, how quickly a rebuild runs, and how the rolling deploy and database updates are verified afterward.

What buyers ask before running Drupal on Kubernetes

What drives the cost of running Drupal on Kubernetes?

The cost is driven by how much of the platform you already run and how many decisions remain open. The main components are design work (container image layout, file storage, database and cache services, cron jobs, and the deploy pipeline), build work (the image, Helm or manifests, and pipeline code), and verification work (load tests, restore tests and a rehearsed rolling deploy). Costs rise with the number of sites, the amount of custom modules, the choice of shared file storage or object storage, and whether you need high availability for the database. Ask any partner for a quote that lists each component separately, states who pays for cluster operations, and says which items are one-time and which recur, such as security rebuilds and upgrade cycles.

How long does it take to build a Drupal platform on Kubernetes?

Duration depends on the state of your cluster and the number of open decisions, not on Drupal alone. A team with an existing, well-governed cluster, a settled database choice and a working CI pipeline has far less to build than a team starting from bare infrastructure. Time is also consumed by file storage design, identity integration and rehearsals of the deploy with database updates and configuration import. No duration is stated here because none has been supplied for this work. Ask for a written timeline tied to the agreed scope, with milestones for a staging environment, a load test and a rollback rehearsal.

What does the work need from our platform team?

Your platform team needs to own the cluster itself, including node pools, ingress, network policy, the database service, backups and the secrets platform. Kubernetes stores Secrets unencrypted in etcd by default, so your team must confirm encryption at rest and least-privilege RBAC before application secrets are added. Your team also needs to provide a container registry, a CI runner, DNS and TLS, and an identity provider for administrator access. Confirm these items before the scope is agreed, because gaps in them move cost and time into the build.

Can our in-house team build and run Drupal on Kubernetes without a partner?

Yes, a capable in-house team can do this, and the decision depends on skills and capacity rather than on Drupal licensing, since Drupal is GPL-2.0-or-later software with no paid edition. The team needs working knowledge of PHP, Composer builds, Drupal's database update and configuration import steps, Kubernetes workloads, and etcd and cluster upgrades. Be honest about the ongoing load: the upgrade path, supported PHP versions and security releases recur. Ask whether the people who build the platform will also carry the on-call and rebuild work after launch, and whether that is funded.

How do Drupal security releases affect image rebuilds?

Drupal security releases force image rebuilds because the code is baked into the container image. Drupal core publishes security releases on the third Wednesday of the month, and bugfix releases on the first Wednesday, so your pipeline should expect a regular rebuild cadence. Each rebuild should pull the updated Composer dependencies, run the test suite, produce a new tagged image and roll it out with the same database update step. Plan who approves an out-of-band rebuild, how long a rollback takes, and how the image registry retains old tags. Confirm the release calendar on the Drupal core release schedule before setting your process.

Which Drupal and Kubernetes versions should we plan around?

Start with the Drupal version that your modules support and your PHP runtime can run. Drupal 10 requires PHP 8.1 or later, Drupal 11 requires PHP 8.3 or later and Drupal 12 requires PHP 8.5 or later, and no supported Drupal version runs on PHP 7. Drupal 10 reaches end of life on December 9, 2026, according to the core release schedule, so a new build should target Drupal 11 unless there is a documented reason otherwise. On the cluster side, the Kubernetes project maintains only the three most recent minor releases, so the upgrade plan must include minor version steps that follow the version skew policy.

What should a quote for Drupal on Kubernetes contain?

A useful quote lists the written scope, deliverables and assumptions before any price. It should separate one-time work, such as design, build, integration, load testing and the first rehearsed deploy, from recurring work, such as security rebuilds, upgrades and monitoring support. It should name the systems you must provide, the environments covered, the acceptance tests and who signs them off. DeployOpen works from a written scope with agreed deliverables and timelines, and it does not publish a price list, so a quote follows from that scope. Ask for the assumptions behind every line, because they determine the final cost.

Does DeployOpen certify our Drupal platform for compliance?

No. DeployOpen prepares systems, controls and evidence for compliance assessments, but independent auditors and certification bodies issue audit reports, attestations and certifications. For a Kubernetes-hosted Drupal platform, evidence usually covers access control to Secrets, encryption at rest for etcd, image provenance, backup and restore records and change history for deploys. Ask any partner which evidence they will produce, in what format, and which parts remain your responsibility to maintain after handover.

When a simpler hosting model is the better choice

Kubernetes is the wrong default for many Drupal estates. A single virtual machine or a managed platform running Nginx or Apache, PHP-FPM and a managed MySQL, MariaDB or PostgreSQL database is usually easier to operate when the team has no container practice, runs one or two sites, and has no need for horizontal scaling that a load balancer and a second web node cannot meet. In that case the cluster adds a control plane, image pipelines, ingress, secrets handling and an etcd backup routine that someone must own for years. Before choosing Kubernetes, ask who will patch the nodes, rotate certificates and respond to a failed upgrade, and whether those people already do this for other workloads.

The number of sites and how tightly they are coupled matters as much as traffic. A small set of independent sites on separate databases can share a simpler host with fewer moving parts. If the estate is a core multisite installation, a shared codebase means one release train, so a Kubernetes rollout does not reduce the coupling; it only adds a layer on top of it. Confirm whether the sites need separate release schedules, separate hostnames with separate settings, or a shared pool of workers. Those answers decide whether the platform work pays back or whether a well-maintained VM with a tested deploy script is the more reliable option.

Ask the team which operations it already runs well. If it operates Kubernetes for other products, reusing its cluster, GitOps tooling and monitoring keeps the Drupal workload small and predictable. If it does not, the first year of Drupal on Kubernetes becomes a platform project with its own backlog, and the Drupal team waits on it. Choose the hosting model that the existing operations team can support through a Drupal security release, a PHP version change and a database upgrade without special handling. Confirm that answer with your own operations staff before the architecture is fixed.

How DeployOpen scopes and delivers Drupal on Kubernetes

DeployOpen plans, builds, documents and supports self-hosted Drupal on Kubernetes inside your own cloud accounts, data centers or air-gapped networks. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts, and ongoing support is available as a retainer.

How we scope

  • Written scope lists the Drupal version, PHP runtime, database service and the cluster you will operate.
  • Scope records how files are stored, whether on shared volumes or object storage, and how they are served.
  • Scope names cron jobs, queue workers, cache services and the deploy steps that run database updates and config import.

How we build

  • Container images are built from a Composer-managed codebase, with code kept separate from files and environment settings.
  • Manifests or Helm charts define stateless PHP pods, cron as Kubernetes jobs, health probes and resource limits.
  • Rolling deploys are tested in a staging cluster, including database updates and configuration import before production.

How we hand over

  • Handover includes runbooks for deploys, rollbacks, etcd backups and restoration of database and file storage.
  • Documentation covers secrets handling, RBAC boundaries, Pod Security settings and the image rebuild process for security releases.
  • Your team receives the test results, configuration repository and a list of decisions and open risks from the build.

How we support

  • Support retainers can cover Drupal core and contributed module updates, Kubernetes upgrades and cluster patching.
  • Upgrade work follows the supported Kubernetes version window and the Drupal release schedule, with scope agreed in advance.
  • Ongoing testing and monitoring reviews can be added to the retainer, with frequency and coverage set in the written agreement.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.