On our platform team we run bilingual Drupal sites with a 99.95% uptime target and a platform team of three. Zero-downtime deploys are a requirement for us.

The pattern

We use a straightforward blue/green setup:

  1. Build an immutable image with code and Composer dependencies baked in.
  2. Start the new pods next to the old ones, on the same database.
  3. Run drush deploy from a one-off Job, not from a pod startup hook.
  4. Move traffic over only when the new pods pass a readiness check that includes a Drupal bootstrap.

Why config import is the hard part

Code is easy to swap. Configuration isn't, because both versions share one database during the switchover. Our rule is that every config change must be backwards compatible for one release. Removing a field takes two deploys: first stop using it, then delete it.

Bilingual gotchas

Translations imported during locale:update can lock tables on large sites. We run them in a separate, scheduled job outside peak hours.

Open source

Our Helm chart is published, and three other governments now use it. You can find it in the project pipeline under Government Drupal Helm Chart.