Docker Compose Notes
Docker Compose Notes
Section titled “Docker Compose Notes”Docker Compose simplifies running multi-container applications on a single host. This guide covers service organization, daily operations, and maintenance tasks.
Directory Structure
Section titled “Directory Structure”Organize your services in a clear directory layout:
/srv/apps/├── dashboard/│ ├── compose.yaml│ ├── .env│ └── data/├── database/│ ├── compose.yaml│ ├── .env│ └── data/└── monitoring/ ├── compose.yaml ├── .env └── data/Each service gets its own directory with:
compose.yaml— Service definition.env— Environment variables (never commit to git)data/— Persistent volumes
Basic Service Definition
Section titled “Basic Service Definition”Here’s a minimal compose.yaml for a web application:
version: '3.8'
services: app: image: ghcr.io/example/myapp:latest restart: unless-stopped ports: - "8080:8080" environment: - LOG_LEVEL=info - DATABASE_URL=postgres://db:5432/myapp volumes: - ./data:/app/data depends_on: - db networks: - app-network
db: image: postgres:15-alpine restart: unless-stopped environment: - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=myapp volumes: - ./data/postgres:/var/lib/postgresql/data networks: - app-network
networks: app-network: driver: bridgeDaily Operations
Section titled “Daily Operations”Start Services
Section titled “Start Services”cd /srv/apps/dashboarddocker compose up -dCheck Status
Section titled “Check Status”docker compose psOutput shows running containers, ports, and status.
View Logs
Section titled “View Logs”# All servicesdocker compose logs --tail=50
# Specific servicedocker compose logs app --tail=50
# Follow logs in real-timedocker compose logs -f appStop Services
Section titled “Stop Services”# Graceful stop (waits for containers to shut down)docker compose stop
# Force stop (immediate termination)docker compose killRestart Services
Section titled “Restart Services”# Restart all servicesdocker compose restart
# Restart specific servicedocker compose restart appMaintenance Tasks
Section titled “Maintenance Tasks”Update Images
Section titled “Update Images”# Pull latest imagesdocker compose pull
# Recreate containers with new imagesdocker compose up -dClean Up
Section titled “Clean Up”# Remove stopped containersdocker compose rm -f
# Remove unused imagesdocker image prune -a
# Remove unused volumes (⚠️ data loss)docker volume pruneDatabase Backups
Section titled “Database Backups”Create a backup of PostgreSQL data:
docker compose exec db pg_dump -U postgres myapp > backup-$(date +%Y%m%d).sqlRestore from backup:
docker compose exec -T db psql -U postgres myapp < backup-20260601.sqlVerification Commands
Section titled “Verification Commands”| Task | Command | Expected Output |
|---|---|---|
| Services running | docker compose ps | All services show “Up” |
| Network connectivity | docker compose exec app ping db | Receives ICMP replies |
| Database ready | docker compose exec db psql -U postgres -c "SELECT 1" | Returns “1” |
| Port accessible | curl http://localhost:8080 | Service responds |
Troubleshooting
Section titled “Troubleshooting”Container Exits Immediately
Section titled “Container Exits Immediately”Check logs for errors:
docker compose logs appCommon causes:
- Missing environment variables
- Port already in use
- Volume mount permission issues
Network Issues
Section titled “Network Issues”Verify containers can reach each other:
docker compose exec app ping dbCheck network configuration:
docker network lsdocker network inspect app-networkDisk Space Issues
Section titled “Disk Space Issues”Check Docker disk usage:
docker system dfClean up unused resources:
docker system prune -aPermission Denied Errors
Section titled “Permission Denied Errors”If you get permission errors on volumes, fix ownership:
sudo chown -R 1000:1000 /srv/apps/dashboard/dataReplace 1000:1000 with the UID:GID of the container user.
Advanced Configuration
Section titled “Advanced Configuration”Resource Limits
Section titled “Resource Limits”Prevent runaway containers from consuming all resources:
services: app: image: myapp:latest deploy: resources: limits: cpus: '1' memory: 512M reservations: cpus: '0.5' memory: 256MHealth Checks
Section titled “Health Checks”Add health checks to monitor service status:
services: app: image: myapp:latest healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 40sLogging Configuration
Section titled “Logging Configuration”Limit log file size to prevent disk filling:
services: app: image: myapp:latest logging: driver: "json-file" options: max-size: "10m" max-file: "3"Next Steps
Section titled “Next Steps”- Set up monitoring with Prometheus and Grafana
- Configure automated backups to external storage
- Implement log aggregation with ELK or Loki
- Plan disaster recovery procedures
See Troubleshooting for common issues and solutions.