168 lines
6.0 KiB
Markdown
168 lines
6.0 KiB
Markdown
---
|
|
name: deploying-production-migrations
|
|
description: Deploy migrations to production safely using migrate deploy in CI/CD. Use when setting up production deployment pipelines.
|
|
allowed-tools: Read, Write, Edit, Bash
|
|
---
|
|
|
|
# MIGRATIONS-production
|
|
|
|
## Overview
|
|
|
|
Production database migrations require careful orchestration to prevent data loss and downtime. This covers safe migration deployment using `prisma migrate deploy` in CI/CD pipelines, failure handling, and rollback strategies.
|
|
|
|
## Production Migration Commands
|
|
|
|
### Safe Command
|
|
|
|
**prisma migrate deploy**: Applies pending migrations only; records history in `_prisma_migrations`; neither creates migrations nor resets database.
|
|
|
|
```bash
|
|
npx prisma migrate deploy
|
|
```
|
|
|
|
### Prohibited Commands
|
|
|
|
**prisma migrate dev**: Creates migrations, can reset database (development-only)
|
|
**prisma migrate reset**: Drops/recreates database, deletes all data
|
|
**prisma db push**: Bypasses migration history, no rollback capability, risks data loss
|
|
|
|
## CI/CD Integration
|
|
|
|
```yaml
|
|
# GitHub Actions
|
|
name: Deploy to Production
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
jobs:
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
- run: npm ci
|
|
- run: npx prisma generate
|
|
- run: npx prisma migrate deploy
|
|
env:
|
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
- run: npm run deploy
|
|
```
|
|
|
|
```yaml
|
|
# GitLab CI
|
|
deploy-production:
|
|
stage: deploy
|
|
image: node:20
|
|
only: [main]
|
|
environment:
|
|
name: production
|
|
before_script:
|
|
- npm ci && npx prisma generate
|
|
script:
|
|
- npx prisma migrate deploy
|
|
- npm run deploy
|
|
variables:
|
|
DATABASE_URL: $DATABASE_URL_PRODUCTION
|
|
```
|
|
|
|
```dockerfile
|
|
# Docker
|
|
FROM node:20-alpine
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci
|
|
COPY prisma ./prisma
|
|
RUN npx prisma generate
|
|
COPY . .
|
|
CMD ["sh", "-c", "npx prisma migrate deploy && npm start"]
|
|
```
|
|
|
|
## Handling Failed Migrations
|
|
|
|
\*\*Check status
|
|
|
|
\*\*: `npx prisma migrate status` (identifies pending, applied, failed migrations, and schema drift)
|
|
|
|
**Resolution options**:
|
|
|
|
- **Temporary failure**: `npx prisma migrate resolve --applied <name> && npx prisma migrate deploy`
|
|
- **Partially reverted**: `npx prisma migrate resolve --rolled-back <name>`
|
|
- **Buggy migration**: Create new migration to fix: `npx prisma migrate dev --name fix_previous_migration`, then deploy
|
|
|
|
**Manual rollback**: Create down migration (SQL to revert changes), apply via `npx prisma migrate dev --name rollback_* --create-only`
|
|
|
|
## Production Deployment Checklist
|
|
|
|
**Pre-Deployment**: All migrations tested in staging; backup created; rollback plan documented; downtime window scheduled; team notified
|
|
|
|
**Deployment**: Maintenance mode enabled (if needed); run `npx prisma migrate deploy`; verify status; run smoke tests; monitor logs
|
|
|
|
**Post-Deployment**: Verify all migrations applied; check functionality; monitor database performance; disable maintenance mode; document issues
|
|
|
|
## Database Connection Best Practices
|
|
|
|
**Connection pooling**: `DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=10&pool_timeout=20"`
|
|
|
|
**Security**: Never commit DATABASE_URL; use environment variables, CI/CD secrets, or secret management tools (Vault, AWS Secrets Manager)
|
|
|
|
**Read replicas**: Separate migration connection from app connections; migrations always target primary database:
|
|
|
|
```env
|
|
DATABASE_URL="postgresql://primary:5432/db"
|
|
DATABASE_URL_REPLICA="postgresql://replica:5432/db"
|
|
```
|
|
|
|
## Zero-Downtime Migrations
|
|
|
|
**Expand-Contract Pattern**:
|
|
|
|
1. **Expand** (add new column, keep old): `ALTER TABLE "User" ADD COLUMN "email_new" TEXT;` Deploy app writing to both.
|
|
2. **Migrate data**: `UPDATE "User" SET "email_new" = "email"
|
|
|
|
WHERE "email_new" IS NULL;`3. **Contract** (remove old):`ALTER TABLE "User" DROP COLUMN "email"; ALTER TABLE "User" RENAME COLUMN "email_new" TO "email";`
|
|
|
|
**Backwards-compatible**: Make columns optional first, enforce constraints in later migration.
|
|
|
|
## Monitoring and Alerts
|
|
|
|
**Duration tracking**: `time npx prisma migrate deploy`; set alerts for migrations exceeding expected duration
|
|
|
|
**Failure alerts**:
|
|
|
|
```yaml
|
|
- run: npx prisma migrate deploy
|
|
- if: failure()
|
|
run: curl -X POST $SLACK_WEBHOOK -d '{"text":"Production migration failed!"}'
|
|
```
|
|
|
|
**Schema drift detection**: `npx prisma migrate status` fails if schema differs from migrations
|
|
|
|
## Common Production Issues
|
|
|
|
| Issue | Cause | Solution |
|
|
| ----------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
|
|
| Migration hangs | Long-running query, table locks | Identify blocking queries; run during low-traffic window; use `SET statement_timeout = '30s';` in PostgreSQL |
|
|
| Migration fails midway | Constraint violation, data type mismatch | Check migration status; mark as applied if data correct; create fix migration if needed |
|
|
| Out-of-order migrations | Multiple developers creating migrations simultaneously | Merge conflicts in migration files; regenerate if needed; enforce linear history |
|
|
|
|
## Configuration
|
|
|
|
**Shadow Database** (Prisma 6): Not needed for `migrate deploy`, only `migrate dev`
|
|
|
|
```env
|
|
DATABASE_URL="postgresql://..."
|
|
SHADOW_DATABASE_URL="postgresql://...shadow"
|
|
```
|
|
|
|
**Multi-Environment Strategy**:
|
|
|
|
- Development: `npx prisma migrate dev`
|
|
- Staging: `npx prisma migrate deploy` (test production process)
|
|
- Production: `npx prisma migrate deploy` (apply only, never create)
|
|
|
|
## References
|
|
|
|
[Prisma Migrate Deploy Documentation](https://www.prisma.io/docs/orm/prisma-migrate/workflows/deploy) | [Production Best Practices](https://www.prisma.io/docs/orm/prisma-migrate/workflows/production) | [Troubleshooting Migrations](https://www.prisma.io/docs/orm/prisma-migrate/workflows/troubleshooting)
|