Skip to content
Decision: database migrations ship as a forward/backward contract, run by an init container

Decision: database migrations ship as a forward/backward contract, run by an init container

September 10, 2026· DecisionDeployment·Elliot Forbes
Elliot Forbes

Milestone 1 of Theseus database migrations has an agreed shape:

  • Migrations are an API contract. A modular feature supplies a forward migration and its corresponding backward migration; any conforming tool can take the pair and run it. The contract — not any particular tool — is what teams write against.
  • An init container runs them. On deploy, an init container applies the supplied migrations against the service’s database. The implementation is migrator — a Go CLI shipped as an init-container image, built on the LabKit v2 Postgres client and the Fairway setup, that validates, applies, and rolls back a modular feature’s Postgres migrations.
  • Fairway wires it in automatically. When a service declares a Postgres dependency with migrations: true, the generated chart deploys the init container — no per-team plumbing.
  • The contract evolves additively. Starting from the simplest possible API (“a forward plus a backward migration”) means new capabilities arrive as additive changes, and teams opt in by pinning newer init-container versions.

Two conditions shaped the acceptance: the API must be able to evolve to support whatever the Data Engineering team’s designs require, and Data Engineering’s buy-in was needed — both are met, with the agreement recorded on the linked thread. Reusing the monolith’s migration machinery stays an open option: anything adopted from it would simply be adapted to the same forward/backward contract.

The runner lives at gitlab-org/theseus/migrator. Ongoing design work has a home in the database migration platform summary, and the delivery roadmap lives on the Theseus: Database Migration epic.

Last updated on