feat(docker): protect production database with external volume

- Mark postgres_data_prod as external volume (slc_postgres_prod_data)
- External volumes are NOT deleted by 'docker compose down -v'
- Add volume creation step to production deployment guide
- Document volume safety measures and dangerous commands
- Add shell alias examples for safe volume management
- Update security checklist with volume creation requirement

Protection: Production database now requires manual volume deletion,
preventing accidental data loss during container management.
This commit is contained in:
Radosław Gierwiało
2025-12-06 12:36:27 +01:00
parent d98222da12
commit f284eb3f2e
2 changed files with 96 additions and 2 deletions

View File

@@ -246,7 +246,8 @@ volumes:
postgres_data:
driver: local
postgres_data_prod:
driver: local
external: true
name: slc_postgres_prod_data
networks:
slc_network:

View File

@@ -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)