How to Run Database Migrations as a Job Before Deploy in GitHub Actions
Apply a one-shot Job that runs the migration, wait for it with kubectl wait, then roll out the app so new pods never hit an old schema.
Create a Job from the new image that runs the migration command, kubectl wait for its completion, and only then apply the Deployment.
Steps
- Apply a Job that runs the migration with the new image tag.
- Wait with
kubectl wait --for=condition=complete job/migrate --timeout. - Apply or upgrade the Deployment after the Job succeeds.
Workflow
.github/workflows/deploy.yml
steps:
- run: kubectl apply -f k8s/migrate-job.yaml -n prod
- run: |
kubectl wait --for=condition=complete job/migrate \
-n prod --timeout=300s
- run: kubectl apply -f k8s/deployment.yaml -n prodmigrate-job.yaml
migrate-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: migrate
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: ghcr.io/acme/app:latest
command: ['npm', 'run', 'migrate']Related guides
How to Wait for a Rollout to Finish From CI in GitHub ActionsMake a GitHub Actions deploy fail loudly when pods do not become ready by running kubectl rollout status with…
How to Create or Update a Kubernetes Secret From CI in GitHub ActionsCreate or update a Kubernetes Secret idempotently from GitHub Actions by piping kubectl create secret through…