Sanitized mirror from private repository - 2026-04-19 08:32:25 UTC
This commit is contained in:
419
DOCKER_COMPOSE_GUIDE.md
Normal file
419
DOCKER_COMPOSE_GUIDE.md
Normal file
@@ -0,0 +1,419 @@
|
||||
# 🐳 Docker Compose Guide
|
||||
|
||||
*Comprehensive guide for Docker Compose best practices in the homelab*
|
||||
|
||||
## Overview
|
||||
This guide covers Docker Compose best practices, patterns, and standards used throughout the homelab infrastructure for consistent, maintainable, and secure container deployments.
|
||||
|
||||
## File Structure Standards
|
||||
|
||||
### Naming Conventions
|
||||
- **Service files**: `service-name.yml` or `service-name.yaml`
|
||||
- **Stack names**: Use descriptive, kebab-case names
|
||||
- **Container names**: Include service and host identifier
|
||||
- **Volume names**: Prefix with service name for clarity
|
||||
|
||||
### Directory Organization
|
||||
```
|
||||
host-name/
|
||||
├── service-name/
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── .env
|
||||
│ ├── config/
|
||||
│ └── data/
|
||||
└── service-name.yml (simple services)
|
||||
```
|
||||
|
||||
## Compose File Best Practices
|
||||
|
||||
### Version and Services
|
||||
```yaml
|
||||
version: '3.8' # Use stable version
|
||||
|
||||
services:
|
||||
service-name:
|
||||
image: official/image:tag # Always pin versions
|
||||
container_name: service-name-hostname
|
||||
restart: unless-stopped # Standard restart policy
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
```yaml
|
||||
# Prefer environment files
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
# Or explicit environment variables
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/New_York
|
||||
```
|
||||
|
||||
### Volume Management
|
||||
```yaml
|
||||
volumes:
|
||||
# Named volumes for data persistence
|
||||
- service-data:/app/data
|
||||
|
||||
# Bind mounts for configuration
|
||||
- ./config:/app/config:ro
|
||||
|
||||
# Host paths for media/large data
|
||||
- /mnt/storage/media:/media:ro
|
||||
|
||||
volumes:
|
||||
service-data:
|
||||
driver: local
|
||||
```
|
||||
|
||||
### Network Configuration
|
||||
```yaml
|
||||
networks:
|
||||
default:
|
||||
name: service-network
|
||||
|
||||
# Or use existing networks
|
||||
proxy:
|
||||
external: true
|
||||
name: nginx-proxy-manager_default
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### User and Permissions
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
user: "1000:1000" # Run as non-root user
|
||||
|
||||
# Or use environment variables
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
```
|
||||
|
||||
### Resource Limits
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
cpus: '0.5'
|
||||
reservations:
|
||||
memory: 256M
|
||||
```
|
||||
|
||||
### Security Options
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# Read-only root filesystem when possible
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp
|
||||
- /var/tmp
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Reverse Proxy Integration
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
labels:
|
||||
# Nginx Proxy Manager
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.app.rule=Host(`app.domain.com`)"
|
||||
|
||||
# Or Traefik labels
|
||||
- "traefik.http.services.app.loadbalancer.server.port=8080"
|
||||
```
|
||||
|
||||
### Health Checks
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
```
|
||||
|
||||
### Dependency Management
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
|
||||
database:
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "postgres"]
|
||||
```
|
||||
|
||||
## GitOps Integration
|
||||
|
||||
### Portainer Stack Deployment
|
||||
- **Repository**: `https://git.vish.gg/Vish/homelab.git`
|
||||
- **Branch**: `main`
|
||||
- **Compose file path**: `host-name/service-name.yml`
|
||||
- **Environment variables**: Managed in Portainer UI
|
||||
|
||||
### File Path Standards
|
||||
```
|
||||
Atlantis/service-name.yml # Primary NAS services
|
||||
Calypso/service-name.yml # Secondary NAS services
|
||||
homelab_vm/service-name.yml # VM-based services
|
||||
concord_nuc/service-name.yml # NUC services
|
||||
raspberry-pi-5-vish/service-name.yml # Pi services
|
||||
```
|
||||
|
||||
### Environment File Management
|
||||
```bash
|
||||
# .env file structure
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
TZ=America/New_York
|
||||
SERVICE_PORT=8080
|
||||
DATA_PATH=/mnt/storage/service-name
|
||||
```
|
||||
|
||||
## Service Categories
|
||||
|
||||
### Media Services
|
||||
```yaml
|
||||
services:
|
||||
plex:
|
||||
image: plexinc/pms-docker:latest
|
||||
environment:
|
||||
- PLEX_CLAIM=claim-token
|
||||
- PLEX_UID=1000
|
||||
- PLEX_GID=1000
|
||||
volumes:
|
||||
- plex-config:/config
|
||||
- /mnt/media:/media:ro
|
||||
ports:
|
||||
- "32400:32400"
|
||||
```
|
||||
|
||||
### Database Services
|
||||
```yaml
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
environment:
|
||||
- POSTGRES_DB=appdb
|
||||
- POSTGRES_USER=appuser
|
||||
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
|
||||
secrets:
|
||||
- db_password
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
|
||||
secrets:
|
||||
db_password:
|
||||
"REDACTED_PASSWORD" ./secrets/db_password.txt
|
||||
```
|
||||
|
||||
### Web Applications
|
||||
```yaml
|
||||
services:
|
||||
webapp:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./html:/usr/share/nginx/html:ro
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.webapp.rule=Host(`app.local`)"
|
||||
```
|
||||
|
||||
## Monitoring Integration
|
||||
|
||||
### Prometheus Metrics
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
labels:
|
||||
- "prometheus.io/scrape=true"
|
||||
- "prometheus.io/port=9090"
|
||||
- "prometheus.io/path=/metrics"
|
||||
```
|
||||
|
||||
### Logging Configuration
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Or use centralized logging
|
||||
logging:
|
||||
driver: "loki"
|
||||
options:
|
||||
loki-url: "http://loki:3100/loki/api/v1/push"
|
||||
```
|
||||
|
||||
## Backup Considerations
|
||||
|
||||
### Volume Backup Strategy
|
||||
```yaml
|
||||
# Backup-friendly volume structure
|
||||
volumes:
|
||||
app-config:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: /mnt/backup/app/config
|
||||
|
||||
app-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: /mnt/backup/app/data
|
||||
```
|
||||
|
||||
### Database Backup
|
||||
```yaml
|
||||
services:
|
||||
db-backup:
|
||||
image: postgres:15-alpine
|
||||
command: |
|
||||
sh -c "
|
||||
while true; do
|
||||
pg_dump -h postgres -U $$POSTGRES_USER $$POSTGRES_DB > /backup/backup_$$(date +%Y%m%d_%H%M%S).sql
|
||||
sleep 86400
|
||||
done"
|
||||
volumes:
|
||||
- ./backups:/backup
|
||||
depends_on:
|
||||
- postgres
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Port Conflicts
|
||||
```bash
|
||||
# Check port usage
|
||||
netstat -tulpn | grep :8080
|
||||
docker ps --format "table {{.Names}}\t{{.Ports}}"
|
||||
```
|
||||
|
||||
#### Volume Permissions
|
||||
```bash
|
||||
# Fix volume permissions
|
||||
sudo chown -R 1000:1000 /path/to/volume
|
||||
sudo chmod -R 755 /path/to/volume
|
||||
```
|
||||
|
||||
#### Network Issues
|
||||
```bash
|
||||
# Inspect networks
|
||||
docker network ls
|
||||
docker network inspect network-name
|
||||
|
||||
# Test connectivity
|
||||
docker exec container-name ping other-container
|
||||
```
|
||||
|
||||
### Debugging Commands
|
||||
```bash
|
||||
# View logs
|
||||
docker-compose logs -f service-name
|
||||
|
||||
# Execute commands in container
|
||||
docker-compose exec service-name bash
|
||||
|
||||
# Validate compose file
|
||||
docker-compose config
|
||||
|
||||
# Check service status
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Resource Management
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
cpus: '1.0'
|
||||
|
||||
# Use init system for proper signal handling
|
||||
init: true
|
||||
|
||||
# Optimize for specific workloads
|
||||
sysctls:
|
||||
- net.core.somaxconn=1024
|
||||
```
|
||||
|
||||
### Storage Optimization
|
||||
```yaml
|
||||
# Use tmpfs for temporary data
|
||||
tmpfs:
|
||||
- /tmp:size=100M,noexec,nosuid,nodev
|
||||
|
||||
# Optimize volume drivers
|
||||
volumes:
|
||||
fast-data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: tmpfs
|
||||
device: tmpfs
|
||||
o: size=1G
|
||||
```
|
||||
|
||||
## Validation and Testing
|
||||
|
||||
### Pre-deployment Checks
|
||||
```bash
|
||||
# Validate syntax
|
||||
docker-compose config
|
||||
|
||||
# Check for security issues
|
||||
docker-compose config | docker run --rm -i hadolint/hadolint
|
||||
|
||||
# Test deployment
|
||||
docker-compose up --dry-run
|
||||
```
|
||||
|
||||
### Health Monitoring
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [GitOps Deployment Guide](docs/GITOPS_DEPLOYMENT_GUIDE.md) - GitOps workflow and deployment procedures
|
||||
- [Security Guidelines](docs/security/SECURITY_GUIDELINES.md) - Security best practices for containers
|
||||
- [Monitoring Architecture](docs/MONITORING_ARCHITECTURE.md) - Monitoring and observability setup
|
||||
|
||||
---
|
||||
**Status**: ✅ Docker Compose standards implemented across all homelab services
|
||||
Reference in New Issue
Block a user