mirror of
https://github.com/basnijholt/compose-farm.git
synced 2026-02-03 14:13:26 +00:00
382 lines
7.2 KiB
Markdown
382 lines
7.2 KiB
Markdown
---
|
|
icon: lucide/lightbulb
|
|
---
|
|
|
|
# Best Practices
|
|
|
|
Tips, limitations, and recommendations for using Compose Farm effectively.
|
|
|
|
## Limitations
|
|
|
|
### No Cross-Host Networking
|
|
|
|
Compose Farm moves containers between hosts but **does not provide cross-host networking**. Docker's internal DNS and networks don't span hosts.
|
|
|
|
**What breaks when you move a service:**
|
|
|
|
| Feature | Works? | Why |
|
|
|---------|--------|-----|
|
|
| `http://redis:6379` | No | Docker DNS doesn't cross hosts |
|
|
| Docker network names | No | Networks are per-host |
|
|
| `DATABASE_URL=postgres://db:5432` | No | Container name won't resolve |
|
|
| Host IP addresses | Yes | Use `192.168.1.10:5432` |
|
|
|
|
### What Compose Farm Doesn't Do
|
|
|
|
- No overlay networking (use Swarm/Kubernetes)
|
|
- No service discovery across hosts
|
|
- No automatic dependency tracking between compose files
|
|
- No health checks or restart policies beyond Docker's
|
|
- No secrets management beyond Docker's
|
|
|
|
## Service Organization
|
|
|
|
### Keep Dependencies Together
|
|
|
|
If services talk to each other, keep them in the same compose file on the same host:
|
|
|
|
```yaml
|
|
# /opt/compose/myapp/docker-compose.yml
|
|
services:
|
|
app:
|
|
image: myapp
|
|
depends_on:
|
|
- db
|
|
- redis
|
|
|
|
db:
|
|
image: postgres
|
|
|
|
redis:
|
|
image: redis
|
|
```
|
|
|
|
```yaml
|
|
# compose-farm.yaml
|
|
services:
|
|
myapp: nuc # All three containers stay together
|
|
```
|
|
|
|
### Separate Standalone Services
|
|
|
|
Services that don't talk to other containers can be anywhere:
|
|
|
|
```yaml
|
|
services:
|
|
# These can run on any host
|
|
plex: nuc
|
|
jellyfin: hp
|
|
homeassistant: nas
|
|
|
|
# These should stay together
|
|
myapp: nuc # includes app + db + redis
|
|
```
|
|
|
|
### Cross-Host Communication
|
|
|
|
If services MUST communicate across hosts, publish ports:
|
|
|
|
```yaml
|
|
# Instead of
|
|
DATABASE_URL=postgres://db:5432
|
|
|
|
# Use
|
|
DATABASE_URL=postgres://192.168.1.10:5432
|
|
```
|
|
|
|
```yaml
|
|
# And publish the port
|
|
services:
|
|
db:
|
|
ports:
|
|
- "5432:5432"
|
|
```
|
|
|
|
## Multi-Host Services
|
|
|
|
### When to Use `all`
|
|
|
|
Use `all` for services that need local access to each host:
|
|
|
|
```yaml
|
|
services:
|
|
# Need Docker socket
|
|
dozzle: all # Log viewer
|
|
portainer-agent: all # Portainer agents
|
|
autokuma: all # Auto-creates monitors
|
|
|
|
# Need host metrics
|
|
node-exporter: all # Prometheus metrics
|
|
promtail: all # Log shipping
|
|
```
|
|
|
|
### Host-Specific Lists
|
|
|
|
For services on specific hosts only:
|
|
|
|
```yaml
|
|
services:
|
|
# Only on compute nodes
|
|
gitlab-runner: [nuc, hp]
|
|
|
|
# Only on storage nodes
|
|
minio: [nas-1, nas-2]
|
|
```
|
|
|
|
## Migration Safety
|
|
|
|
### Pre-flight Checks
|
|
|
|
Before migrating, Compose Farm verifies:
|
|
- Compose file is accessible on new host
|
|
- Required mounts exist on new host
|
|
- Required networks exist on new host
|
|
|
|
### Data Considerations
|
|
|
|
**Compose Farm doesn't move data.** Ensure:
|
|
|
|
1. **Shared storage**: Data volumes on NFS/shared storage
|
|
2. **External databases**: Data in external DB, not container
|
|
3. **Backup first**: Always backup before migration
|
|
|
|
### Safe Migration Pattern
|
|
|
|
```bash
|
|
# 1. Preview changes
|
|
cf apply --dry-run
|
|
|
|
# 2. Verify target host can run the service
|
|
cf check myservice
|
|
|
|
# 3. Apply changes
|
|
cf apply
|
|
```
|
|
|
|
## State Management
|
|
|
|
### When to Refresh
|
|
|
|
Run `cf refresh` after:
|
|
- Manual `docker compose` commands
|
|
- Container restarts
|
|
- Host reboots
|
|
- Any changes outside Compose Farm
|
|
|
|
```bash
|
|
cf refresh --dry-run # Preview
|
|
cf refresh # Sync
|
|
```
|
|
|
|
### State Conflicts
|
|
|
|
If state doesn't match reality:
|
|
|
|
```bash
|
|
# See what's actually running
|
|
cf refresh --dry-run
|
|
|
|
# Sync state
|
|
cf refresh
|
|
|
|
# Then apply config
|
|
cf apply
|
|
```
|
|
|
|
## Shared Storage
|
|
|
|
### NFS Best Practices
|
|
|
|
```bash
|
|
# Mount options for Docker compatibility
|
|
nas:/compose /opt/compose nfs rw,hard,intr,rsize=8192,wsize=8192 0 0
|
|
```
|
|
|
|
### Directory Ownership
|
|
|
|
Ensure consistent UID/GID across hosts:
|
|
|
|
```yaml
|
|
services:
|
|
myapp:
|
|
environment:
|
|
- PUID=1000
|
|
- PGID=1000
|
|
```
|
|
|
|
### Config vs Data
|
|
|
|
Keep config and data separate:
|
|
|
|
```
|
|
/opt/compose/ # Shared: compose files + config
|
|
├── plex/
|
|
│ ├── docker-compose.yml
|
|
│ └── config/ # Small config files OK
|
|
|
|
/mnt/data/ # Shared: large media files
|
|
├── movies/
|
|
├── tv/
|
|
└── music/
|
|
|
|
/opt/appdata/ # Local: per-host app data
|
|
├── plex/
|
|
└── sonarr/
|
|
```
|
|
|
|
## Performance
|
|
|
|
### Parallel Operations
|
|
|
|
Compose Farm runs operations in parallel. For large deployments:
|
|
|
|
```bash
|
|
# Good: parallel by default
|
|
cf up --all
|
|
|
|
# Avoid: sequential updates when possible
|
|
for svc in plex sonarr radarr; do
|
|
cf update $svc
|
|
done
|
|
```
|
|
|
|
### SSH Connection Reuse
|
|
|
|
SSH connections are reused within a command. For many operations:
|
|
|
|
```bash
|
|
# One command, one connection per host
|
|
cf update --all
|
|
|
|
# Multiple commands, multiple connections (slower)
|
|
cf update plex && cf update sonarr && cf update radarr
|
|
```
|
|
|
|
## Traefik Setup
|
|
|
|
### Service Placement
|
|
|
|
Put Traefik on a reliable host:
|
|
|
|
```yaml
|
|
services:
|
|
traefik: nuc # Primary host with good uptime
|
|
```
|
|
|
|
### Same-Host Services
|
|
|
|
Services on the same host as Traefik use Docker provider:
|
|
|
|
```yaml
|
|
traefik_service: traefik
|
|
|
|
services:
|
|
traefik: nuc
|
|
portainer: nuc # Docker provider handles this
|
|
plex: hp # File provider handles this
|
|
```
|
|
|
|
### Middleware in Separate File
|
|
|
|
Define middlewares outside Compose Farm's generated file:
|
|
|
|
```yaml
|
|
# /opt/traefik/dynamic.d/middlewares.yml
|
|
http:
|
|
middlewares:
|
|
redirect-https:
|
|
redirectScheme:
|
|
scheme: https
|
|
```
|
|
|
|
## Backup Strategy
|
|
|
|
### What to Backup
|
|
|
|
| Item | Location | Method |
|
|
|------|----------|--------|
|
|
| Compose Farm config | `~/.config/compose-farm/` | Git or copy |
|
|
| Compose files | `/opt/compose/` | Git |
|
|
| State file | `~/.config/compose-farm/state.yaml` | Optional (can refresh) |
|
|
| App data | `/opt/appdata/` | Backup solution |
|
|
|
|
### Disaster Recovery
|
|
|
|
```bash
|
|
# Restore config
|
|
cp backup/compose-farm.yaml ~/.config/compose-farm/
|
|
|
|
# Refresh state from running containers
|
|
cf refresh
|
|
|
|
# Or start fresh
|
|
cf apply
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Service won't start:**
|
|
```bash
|
|
cf check myservice # Verify mounts/networks
|
|
cf logs myservice # Check container logs
|
|
```
|
|
|
|
**Migration fails:**
|
|
```bash
|
|
cf check myservice # Verify new host is ready
|
|
cf init-network newhost # Create network if missing
|
|
```
|
|
|
|
**State out of sync:**
|
|
```bash
|
|
cf refresh --dry-run # See differences
|
|
cf refresh # Sync state
|
|
```
|
|
|
|
**SSH issues:**
|
|
```bash
|
|
cf ssh status # Check key status
|
|
cf ssh setup # Re-setup keys
|
|
```
|
|
|
|
### Debug Mode
|
|
|
|
For more verbose output:
|
|
|
|
```bash
|
|
# See exact commands being run
|
|
cf --verbose up myservice
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
### SSH Keys
|
|
|
|
- Use dedicated SSH key for Compose Farm
|
|
- Limit key to specific hosts if possible
|
|
- Don't store keys in Docker images
|
|
|
|
### Network Exposure
|
|
|
|
- Published ports are accessible from network
|
|
- Use firewalls for sensitive services
|
|
- Consider VPN for cross-host communication
|
|
|
|
### Secrets
|
|
|
|
- Don't commit `.env` files with secrets
|
|
- Use Docker secrets or external secret management
|
|
- Avoid secrets in compose file labels
|
|
|
|
## Comparison: When to Use Alternatives
|
|
|
|
| Scenario | Solution |
|
|
|----------|----------|
|
|
| 2-10 hosts, static services | **Compose Farm** |
|
|
| Cross-host container networking | Docker Swarm |
|
|
| Auto-scaling, self-healing | Kubernetes |
|
|
| Infrastructure as code | Ansible + Compose Farm |
|
|
| High availability requirements | Kubernetes or Swarm |
|