diff --git a/docker-compose.yml b/docker-compose.yml index 902a688..9442e28 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -246,7 +246,8 @@ volumes: postgres_data: driver: local postgres_data_prod: - driver: local + external: true + name: slc_postgres_prod_data networks: slc_network: diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 8276b3d..718fdc6 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -88,7 +88,16 @@ Edit `backend/.env.production`: - Add AWS SES credentials - Set production `CORS_ORIGIN` -4. **Build production images** +4. **Create production database volume** +```bash +# IMPORTANT: Create external volume before first production start +# This protects the database from accidental deletion with 'docker compose down -v' +docker volume create slc_postgres_prod_data +``` + +This external volume will NOT be deleted even with `docker compose down -v`. + +5. **Build production images** ```bash docker compose --profile prod build ``` @@ -269,6 +278,89 @@ cat backups/backup_YYYYMMDD_HHMMSS.sql | docker exec -i spotlightcam-db psql -U --- +## Volume Safety & Data Protection + +### Production Database Volume Protection + +The production database uses an **external volume** (`slc_postgres_prod_data`) that is protected from accidental deletion: + +```yaml +volumes: + postgres_data_prod: + external: true + name: slc_postgres_prod_data +``` + +**Key Safety Features:** +- ✅ **NOT deleted** by `docker compose down` +- ✅ **NOT deleted** by `docker compose down -v` (even with volumes flag!) +- ✅ **Survives** container recreation and rebuilds +- ⚠️ Must be manually created before first production deployment + +**Volume Commands:** +```bash +# Create volume (before first deployment) +docker volume create slc_postgres_prod_data + +# List volumes +docker volume ls + +# Inspect volume +docker volume inspect slc_postgres_prod_data + +# Manual deletion (if absolutely necessary) +docker volume rm slc_postgres_prod_data # Requires manual confirmation +``` + +### Safe vs Dangerous Commands + +**SAFE - Will NOT delete data:** +```bash +docker compose down # Removes containers only +docker compose --profile prod down # Removes prod containers only +docker compose restart # Restart containers +docker compose up --build # Rebuild and restart +``` + +**DANGEROUS - Could delete development data:** +```bash +docker compose down -v # Deletes dev volumes (postgres_data) +docker compose down --volumes # Same as above +``` + +**PROTECTED - Production database is safe even with:** +```bash +docker compose --profile prod down -v # prod volume is EXTERNAL, won't be deleted +``` + +### Additional Safety Measures + +**1. Shell Aliases (add to ~/.bashrc or ~/.zshrc):** +```bash +# Safe shutdown +alias dcd='echo "✅ docker compose down - volumes SAFE"; docker compose down' + +# Dangerous shutdown with confirmation +alias dcdv='echo "🚨 WARNING! docker compose down -v DELETES VOLUMES!"; \ + echo "Type YES to continue:"; read response; \ + [ "$response" = "YES" ] && docker compose down -v || echo "❌ Cancelled"' +``` + +**2. Regular Backups:** +Always maintain automated backups regardless of volume protection: +```bash +# Daily backup at 2 AM +0 2 * * * docker compose exec db-prod pg_dump -U spotlightcam spotlightcam | gzip > /backups/db-$(date +\%Y\%m\%d).sql.gz +``` + +**3. Pre-deployment Checklist:** +- [ ] Production volume created: `docker volume ls | grep slc_postgres_prod_data` +- [ ] Volume is marked as external in docker-compose.yml +- [ ] Backup script is configured and tested +- [ ] Team knows NOT to use `-v` flag on production + +--- + ## Monitoring & Logging ### View logs @@ -312,6 +404,7 @@ Logs are configured with rotation: ### Before Going to Production +- [ ] **Create external database volume:** `docker volume create slc_postgres_prod_data` - [ ] Generate strong JWT secret (64+ characters) - [ ] Use strong database password (20+ characters) - [ ] Configure AWS SES in production mode (not sandbox)