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:
@@ -246,7 +246,8 @@ volumes:
|
|||||||
postgres_data:
|
postgres_data:
|
||||||
driver: local
|
driver: local
|
||||||
postgres_data_prod:
|
postgres_data_prod:
|
||||||
driver: local
|
external: true
|
||||||
|
name: slc_postgres_prod_data
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
slc_network:
|
slc_network:
|
||||||
|
|||||||
@@ -88,7 +88,16 @@ Edit `backend/.env.production`:
|
|||||||
- Add AWS SES credentials
|
- Add AWS SES credentials
|
||||||
- Set production `CORS_ORIGIN`
|
- 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
|
```bash
|
||||||
docker compose --profile prod build
|
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
|
## Monitoring & Logging
|
||||||
|
|
||||||
### View logs
|
### View logs
|
||||||
@@ -312,6 +404,7 @@ Logs are configured with rotation:
|
|||||||
|
|
||||||
### Before Going to Production
|
### Before Going to Production
|
||||||
|
|
||||||
|
- [ ] **Create external database volume:** `docker volume create slc_postgres_prod_data`
|
||||||
- [ ] Generate strong JWT secret (64+ characters)
|
- [ ] Generate strong JWT secret (64+ characters)
|
||||||
- [ ] Use strong database password (20+ characters)
|
- [ ] Use strong database password (20+ characters)
|
||||||
- [ ] Configure AWS SES in production mode (not sandbox)
|
- [ ] Configure AWS SES in production mode (not sandbox)
|
||||||
|
|||||||
Reference in New Issue
Block a user