How to Run Database Migrations in the Deploy Pipeline
Migrations belong in their own deploy step so a schema change either fully applies or fails the release before code rolls out.
Add a migrate step to the deploy job that runs after build and gates the app rollout. With expand-contract changes you run the expand migration before deploying the new code, and the contract migration in a later release once no old code remains.
Steps
- Run the schema migration as a separate step, before the app rollout.
- Only start the rollout if the migration step exited 0.
- Keep the migration backward compatible so old pods still work mid-rollout.
- Defer any destructive change (drop, not-null) to a later release.
Workflow
.github/workflows/ci.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Apply migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
- name: Roll out app
run: ./deploy.shGotchas
- A migration that fails halfway can leave a partial schema; wrap DDL in a transaction where the engine allows it.
- Never couple an expand and a contract in the same release; that breaks the rollback path.
Related guides
How to Do Zero-Downtime Migrations With Expand-ContractShip zero-downtime schema changes with the expand-contract (parallel change) pattern: expand the schema, migr…
How to Run Migrations as a Separate CI Job With the Right CredsRun migrations in a dedicated CI job with a scoped migration role and secret, separate from the app deploy, s…