CI/CD & Deployment
mmk is built for automation: --json gives machine-readable output on every data command, and mmk status --check exits non-zero when migrations are pending. Here are the recipes that tie it together.
Run migrations on deploy
The simplest and most common pattern — apply pending migrations as a step in your deploy, before the app starts:
mmk upIf it exits non-zero, fail the deploy. The lock guarantees that even if two deploy jobs race, only one runs migrations.
Gate a deploy on a fully-migrated database
Use --check to refuse to proceed when migrations are pending:
mmk status --check || {
echo "Database has pending migrations — blocking deploy"
exit 1
}GitHub Actions
# .github/workflows/migrate.yml
name: Migrate
on:
push:
branches: [main]
jobs:
migrate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx mmk up
env:
MMK_URI: ${{ secrets.MONGO_URI }}
MMK_DB: ${{ secrets.MONGO_DB }}Everything is driven by env vars, so no config file or secrets need to live in the repo.
Docker
In a containerized deploy, run migrations as an init step. Note the host is usually the service name (mongo), not localhost:
# entrypoint.sh
#!/bin/sh
set -e
npx mmk up # apply pending migrations, abort on failure
exec node server.js # then start the appdocker run --rm \
-e MMK_URI="mongodb://mongo:27017" \
-e MMK_DB="my_app" \
my-app npx mmk upConsuming JSON output
Every data command accepts --json and prints a single JSON document to stdout (human logs and the spinner go to stderr, so stdout stays clean to pipe):
mmk up --json | jq '.[] | select(.status == "error")'# Count pending migrations from a script
pending=$(mmk list --pending --json | jq 'length')
echo "$pending migrations pending"On failure, the command prints { "error": { "code": "...", "message": "..." } } and exits 1.
Loading the connection from a secret manager
Don't want connection strings in env vars? A function config can fetch them at runtime — no cloud SDKs are bundled, you bring your own:
mmk init --secret-provider # generates an AWS Secrets Manager template (swap for any provider)See Configuration → async/factory config.
Tips
- Pin a Node version in CI that can run your migrations (≥ 18; ≥ 22.18 if you run
.tswithouttsx). - Run
mmk dry-run upin a pre-deploy check to log exactly what would run. - If a job is killed mid-run and leaves a lock,
mmk unlock --yesclears it in the next job.