Production Database Migrations
This runbook describes how to run database migrations in production environments.
Overview
Database migrations should be run before deploying new application code that depends on schema changes. The admin container provides a safe way to run migrations as a one-off task.
Prerequisites
- Access to run containers in your production environment
- Network access to the production database
- The
everruns-admincontainer image
Migration Strategy
When to Run Migrations
- Pre-deployment: Run migrations before deploying new code that requires schema changes
- Backward-compatible changes: Prefer additive migrations (new tables, new columns with defaults)
- Multi-phase deployments: For breaking changes, use multiple deployments:
- Phase 1: Add new schema (backward compatible)
- Phase 2: Deploy new code
- Phase 3: Remove old schema (if needed)
Migration Execution Flow
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐│ Check Status │────▶│ Run Migrations │────▶│ Deploy New Code ││ (migrate-info) │ │ (migrate) │ │ │└─────────────────┘ └─────────────────┘ └─────────────────┘Procedure
Step 1: Check Current Migration Status
Before running migrations, check which migrations have been applied:
docker run --rm \ -e DATABASE_URL="$DATABASE_URL" \ everruns-admin migrate-infoExpected output shows applied and pending migrations:
20240101000000/installed: 001_initial_schema20240115000000/installed: 002_llm_providers20240201000000/pending: 003_new_feature (NEW)Step 2: Review Pending Migrations
Before applying, review the migration SQL:
ls -la crates/everruns-storage/migrations/cat crates/everruns-storage/migrations/003_new_feature.sqlCheck for:
- Backward compatibility with current code
- Long-running operations (large table alterations)
- Potential locking issues
- Data migrations that might fail
Step 3: Run Migrations
Execute the pending migrations:
docker run --rm \ -e DATABASE_URL="$DATABASE_URL" \ everruns-admin migrateThe task will:
- Connect to the database
- Apply pending migrations in order
- Record applied migrations in
_sqlx_migrationstable - Exit with code 0 on success
Step 4: Verify Migration Success
Confirm migrations were applied:
docker run --rm \ -e DATABASE_URL="$DATABASE_URL" \ everruns-admin migrate-infoAll migrations should show as installed.
Step 5: Deploy Application
Once migrations are verified, proceed with the application deployment.
Rollback Procedure
SQLx does not have built-in rollback. To rollback a migration:
Option 1: Manual Rollback
- Identify the changes made by the migration
- Write and execute reverse SQL manually
- Delete the migration record:
DELETE FROM _sqlx_migrations WHERE version = 20240201000000;
Option 2: Forward-Fix
Often safer than rollback:
- Create a new migration that reverts the changes
- Apply the new migration
- This maintains a clear audit trail
Troubleshooting
Migration Fails Mid-Way
If a migration partially applies:
- Check database state: Verify what was applied
- Fix manually: Apply remaining changes or rollback
- Update migration table: Ensure state is consistent
-- Check migration statusSELECT * FROM _sqlx_migrations ORDER BY version;
-- If needed, mark as applied after manual fixINSERT INTO _sqlx_migrations (version, description, installed_on, success, checksum)VALUES (20240201000000, '003_new_feature', NOW(), true, '...');Container Fails to Start
Common issues:
- Database not reachable: Check network connectivity and credentials
- Invalid DATABASE_URL: Verify connection string format
- Missing secrets: Ensure environment variables are set
Database Connection Timeout
If migrations timeout:
- Check network rules allow database access
- Verify database is accessible from the container environment
- Check database credentials
Emergency: Production Database Issues
If migrations cause production issues:
- Stop the deployment pipeline immediately
- Assess the damage: What queries are failing?
- Decide: rollback or forward-fix
- Rollback if changes are isolated
- Forward-fix if rollback is risky
- Execute the fix using admin container
- Verify application health
- Post-incident review
Best Practices
- Always check status first before running migrations
- Review migration SQL before applying to production
- Test in staging before production
- Prefer additive changes (add columns, not modify)
- Use transactions for multi-statement migrations
- Monitor database metrics during migration
- Have a rollback plan before starting
- Document breaking changes in migration files