Rollback Procedures
This SOP covers rollback procedures for reverting failed deployments and recovering from production incidents.
When to Rollback
Rollback immediately if:
- ❌ Application won't start after deployment
- ❌ Critical functionality broken
- ❌ Database migration failed
- ❌ Security vulnerability introduced
- ❌ Performance degradation >50%
- ❌ User-facing errors affecting >10% of traffic
Investigate before rollback if:
- ⚠️ Minor UI issues (can be hotfixed)
- ⚠️ Non-critical feature not working
- ⚠️ Configuration issue (might be fixable)
- ⚠️ Performance degradation <20%
Quick Rollback (Git Revert)
Fastest method - use when:
- No database migration involved
- Simple code change
- Container won't start
# 1. SSH to VPS
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
# 2. Navigate to project
cd /root/[project-name]
# 3. Check git log to find last working commit
git log --oneline -10
# 4. Revert to previous commit
git reset --hard [commit-hash]
# Example:
# git reset --hard a1b2c3d
# 5. Rebuild containers
docker compose down
docker compose up -d --build
# 6. Verify rollback
docker ps
docker logs -f [container-name]Database Rollback (Prisma)
For Prisma migrations that need reverting:
Method 1: Rollback Migration
# 1. SSH to VPS and enter container
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
docker exec -it [app-container] sh
# 2. Check migration status
npx prisma migrate status
# 3. Revert to specific migration
npx prisma migrate resolve --rolled-back [migration-name]
# 4. Reapply previous migration
npx prisma migrate deploy
# 5. Verify schema
npx prisma db pullMethod 2: Restore Database Backup
# 1. Stop application containers
docker stop [app-container]
# 2. Drop current database and restore backup
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
docker exec [db-container] dropdb -U [user] [dbname]
docker exec -i [db-container] psql -U [user] -d postgres -c "CREATE DATABASE [dbname];"
docker exec -i [db-container] psql -U [user] -d [dbname] < /root/backups/[backup-file].sql
# 3. Restart application
docker start [app-container]Database Rollback (SQLAlchemy/Alembic)
For Alembic migrations:
# 1. SSH to VPS
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
# 2. Enter application container
docker exec -it [container] sh
# 3. Check migration history
alembic history
# 4. Downgrade to previous revision
alembic downgrade -1 # go back one migration
# OR
alembic downgrade [revision-id] # go to specific revision
# 5. Verify schema
alembic currentDocker Image Rollback
If new image is broken but previous image still exists:
# 1. List available images
docker images | grep [project-name]
# 2. Find previous image tag
# Example output:
# expediente latest abc123 2 hours ago
# expediente <none> def456 1 day ago
# 3. Tag previous image as latest
docker tag def456 [project-name]:latest
# 4. Restart container with previous image
docker compose down
docker compose up -d
# 5. Verify
docker psFull Environment Rollback
Complete rollback including code, database, and environment:
1. Prepare Rollback
# Identify target state
git log --oneline -20
git show [commit-hash] # verify this is the working version2. Stop Services
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
cd /root/[project]
# Stop containers
docker compose down3. Rollback Code
# Revert to working commit
git reset --hard [commit-hash]
# Verify correct version
git log -14. Rollback Database (if needed)
Option A: Restore from backup
# Restore PostgreSQL backup
docker exec -i [db-container] psql -U [user] -d postgres -c "DROP DATABASE [dbname];"
docker exec -i [db-container] psql -U [user] -d postgres -c "CREATE DATABASE [dbname];"
docker exec -i [db-container] psql -U [user] -d [dbname] < /root/backups/[backup-file].sqlOption B: Downgrade migration
# For Prisma
docker exec [container] npx prisma migrate resolve --rolled-back [migration]
# For Alembic
docker exec [container] alembic downgrade -15. Restore Environment Variables (if changed)
# Restore .env from backup or git
git show [commit-hash]:.env > .env
# OR manually edit
nano .env6. Restart Services
# Rebuild and start
docker compose up -d --build
# Monitor startup
docker compose logs -f7. Verify Rollback
# Check containers
docker ps
# Check logs
docker logs [container-name]
# Test application
curl -I https://[domain]
# Visual verification in browserPartial Rollback (Hotfix)
When only specific files need reverting:
# 1. SSH to VPS
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
cd /root/[project]
# 2. Checkout specific files from previous commit
git checkout [commit-hash] -- path/to/file.ts
git checkout [commit-hash] -- path/to/another/file.tsx
# 3. Verify changes
git diff
# 4. Rebuild
docker compose down
docker compose up -d --build
# 5. If successful, commit the partial revert
git add -A
git commit -m "hotfix: revert specific files from failed deployment"Emergency Rollback Checklist
When rolling back in an emergency:
- [ ] Notify team - Alert team members of rollback
- [ ] Document issue - Screenshot errors, save logs
- [ ] Stop deployment - Cancel any in-progress deploys
- [ ] Verify backup available - Check database backup exists
- [ ] Execute rollback - Follow procedure above
- [ ] Test thoroughly - Verify rollback successful
- [ ] Monitor metrics - Watch error rates, performance
- [ ] Post-mortem - Document what went wrong and why
- [ ] Fix forward - Address issue before next deploy
Backup Verification
Before any risky deployment, verify backups exist:
# List database backups
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud 'ls -lh /root/backups/ | grep [dbname]'
# Verify backup is recent (within 24 hours)
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud 'find /root/backups/ -name "[dbname]-*.sql" -mtime -1'
# Test backup restore (to temporary database)
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
docker exec -i [db-container] psql -U [user] -d postgres -c "CREATE DATABASE test_restore;"
docker exec -i [db-container] psql -U [user] -d test_restore < /root/backups/[latest-backup].sql
docker exec [db-container] psql -U [user] -d test_restore -c "\dt" # list tables
docker exec [db-container] psql -U [user] -d postgres -c "DROP DATABASE test_restore;"Creating Backups Before Deployment
Always backup before risky deployments:
PostgreSQL Backup
# Manual backup
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
# Create timestamped backup
docker exec [db-container] pg_dump -U [user] [dbname] > /root/backups/[dbname]-$(date +%Y%m%d-%H%M%S).sql
# Verify backup created
ls -lh /root/backups/
# Keep only last 10 backups
cd /root/backups && ls -t [dbname]-*.sql | tail -n +11 | xargs rm -fApplication Files Backup
# Backup entire application directory
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
tar -czf /root/backups/[project]-$(date +%Y%m%d-%H%M%S).tar.gz /root/[project]/
# Verify backup
ls -lh /root/backups/*.tar.gzDocker Image Backup
# Save current Docker image before rebuilding
docker tag [image]:latest [image]:backup-$(date +%Y%m%d-%H%M%S)
# Verify tagged
docker images | grep [image]Rollback Testing
Test rollback procedures regularly:
# 1. In staging environment, make a change
git commit -m "test change for rollback test"
docker compose down && docker compose up -d --build
# 2. Verify new version running
curl https://staging.[domain]
# 3. Practice rollback
git reset --hard HEAD~1
docker compose down && docker compose up -d --build
# 4. Verify rollback successful
curl https://staging.[domain]Common Rollback Scenarios
Scenario 1: Deployment Broke Login
Problem: Users can't login after deployment
Rollback:
# Quick git revert
ssh -i ~/.ssh/id_hostinger root@srv1139900.hstgr.cloud
cd /root/[project]
git reset --hard HEAD~1
docker compose down && docker compose up -d --buildVerify:
# Test login endpoint
curl -X POST https://[domain]/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"test"}'Scenario 2: Database Migration Corrupted Data
Problem: Migration ran but data is now corrupted
Rollback:
# 1. Stop app
docker stop [app-container]
# 2. Restore database from backup
docker exec [db-container] dropdb -U [user] [dbname]
docker exec [db-container] createdb -U [user] [dbname]
docker exec -i [db-container] psql -U [user] -d [dbname] < /root/backups/[latest-backup].sql
# 3. Revert code
cd /root/[project]
git reset --hard [pre-migration-commit]
# 4. Restart app
docker start [app-container]Scenario 3: Environment Variables Misconfigured
Problem: Forgot to update .env, app connecting to wrong services
Rollback:
# 1. Restore .env from previous commit
git show HEAD~1:.env > .env
# 2. Restart containers (MUST restart for env changes)
docker compose down
docker compose up -d
# 3. Verify env vars
docker exec [container] env | grep -E "(DATABASE|API|SECRET)"Scenario 4: Docker Build Failed
Problem: New Dockerfile breaks build
Rollback:
# Revert Dockerfile
git checkout HEAD~1 -- Dockerfile
git checkout HEAD~1 -- docker-compose.yml
# Rebuild
docker compose down
docker compose up -d --buildPost-Rollback Actions
After successful rollback:
Verify application health:
- Test critical user flows
- Check error monitoring (no new errors)
- Monitor performance metrics
Investigate root cause:
- Review deployment logs
- Identify what went wrong
- Document in post-mortem
Fix the issue:
- Create bugfix branch
- Fix the problem locally
- Test thoroughly
- Deploy fix when ready
Update documentation:
- Document what failed
- Update deployment checklist
- Add new test case
Notify stakeholders:
- Update team on status
- Communicate fix timeline
- Document lessons learned
Preventing Rollbacks
Best practices to avoid needing rollbacks:
- ✅ Test in staging first - Always deploy to staging before production
- ✅ Backup before deploy - Create database backup before risky changes
- ✅ Deploy during low traffic - Minimize user impact if rollback needed
- ✅ Use feature flags - Disable new features without code rollback
- ✅ Monitor closely - Watch logs/metrics immediately after deploy
- ✅ Incremental changes - Small, frequent deploys vs. large batches
- ✅ Database migrations - Test migrations thoroughly, use transactions
- ✅ Automated tests - Run test suite before deploying
- ✅ Rollback plan - Know rollback procedure before deploying
- ✅ Team availability - Don't deploy if team unavailable to respond
Last Updated: 2026-02-28 Related SOPs: Deployment SOP, Security Guide