Running Database Migrations
This guide explains how to configure your application to run a pre-deployment database migration job before the main service starts.
Infrastream runs migrations as a lifecycle job. You attach a BEFORE job to your
application and describe it with a JobConfig manifest. The platform provisions a one-off
Cloud Run Job that runs your migration container, and the main service deployment is gated —
it only proceeds after the BEFORE job completes successfully.
Note: The older
runMigrationJobflag has been removed. Use thejobs+JobConfigmodel below.
Prerequisites
- You must have an existing
Applicationmanifest. - Your application's
BuildDefinitionorExternalApplicationshould produce a container image that can run migrations (e.g., a Flyway, Liquibase, or custom migration runner). - You must have a
Databasemanifest provisioned.
Step 1: Declare a BEFORE job on your Application
Reference the migration job in your Application's spec.jobs, and grant it database access:
apiVersion: lowops.manifests.v1
kind: Application
metadata:
name: payment-api
application-set: payments
release-track: main-track
organizational-unit: retail-banking
organization: fincorp
spec:
source: payment-api
container: payment-api
target: CLOUD_RUN
project: payment-gateway
jobs:
- name: migrate
type: BEFORE # Runs before each deployment (also: AFTER, SCHEDULED, ON_DEMAND)
accessControl:
database:
name: payments-db
schema: payments # A logical database declared in the Database's spec.databases
privileges:
- USAGE
- CREATE
secretSource:
envVar: DATABASE_URL
Step 2: Describe the job with a JobConfig manifest
For each environment, create a JobConfig whose metadata.name follows the
<application-name>-<job-name> pattern (here, payment-api-migrate). It reuses the
application's container image and defines the command that runs the migration:
apiVersion: lowops.manifests.v1
kind: JobConfig
metadata:
name: payment-api-migrate # <application-name>-<job-name>
project: payment-gateway
environment: production
organizational-unit: retail-banking
organization: fincorp
spec:
version: "1.4.0" # Image tag to run for the migration
container:
command: ["/migrate.sh"] # Entrypoint that applies your migrations
env:
- name: MIGRATION_MODE
value: "up"
Step 3: Ensure Your Container Supports Migrations
The job reuses the application's container image. Ensure your Dockerfile or build pipeline produces an image that can run migrations when invoked.
Common patterns:
- Flyway / Liquibase: override the entrypoint/command to apply migrations
- Custom scripts: include a
/migrate.shscript that the job invokes
If your migration tool manages schema objects itself, still declare the logical database in the
Database manifest's spec.databases list (and enable any required PostgreSQL extensions
there); the application's accessControl.database only grants privileges — it does not create
tables.
Note: The platform creates a Cloud Run Job for the
BEFOREstep, and the main Cloud Run service is configured to depend on its successful completion.
Step 4: Commit, Review, and Merge
After your PR is merged, the deployment flow becomes:
The migration job runs before every deployment, ensuring your database schema is always up-to-date with the deployed code version.