- Add health checks to all services using Sablier lazy loading - Utilities stack: Backrest, Duplicati, Form.io, Vaultwarden - Productivity stack: Nextcloud, WordPress, Gitea, BookStack, MediaWiki - Media Management stack: Sonarr, Radarr, Prowlarr, Jellyseerr - Infrastructure stack: Dozzle, Glances, Code Server - Dashboards stack: Homarr - Health checks use curl to service endpoints with 30s intervals - Appropriate start_period delays for service initialization - This resolves Sablier warnings about missing health checks
Docker Compose Stacks
This directory contains Docker Compose files for managing your homelab services. Each stack is organized in its own folder for better organization and maintainability.
Structure
docker-compose/
├── core/ # Core infrastructure (Traefik, Authelia, DuckDNS)
├── infrastructure/ # Additional infrastructure (Pi-hole, Dockge, etc.)
├── dashboards/ # Dashboard services (Homepage, Homarr)
├── vpn/ # VPN services (Gluetun, qBittorrent)
├── media/ # Media services (Plex, Jellyfin, etc.)
├── monitoring/ # Observability stack (Prometheus, Grafana, etc.)
├── alternatives/ # Alternative services (Authentik, etc.)
├── homeassistant/ # Home Assistant stack
├── nextcloud/ # Nextcloud stack
├── productivity/ # Productivity tools
├── utilities/ # Utility services
└── README.md # This file
Usage
Starting Services
Start all services in a stack:
cd docker-compose/core && docker compose up -d
Start a specific service:
cd docker-compose/vpn && docker compose up -d gluetun
Stopping Services
Stop all services in a stack:
cd docker-compose/core && docker compose down
Stop a specific service:
cd docker-compose/vpn && docker compose stop qbittorrent
Viewing Status
Check running services:
docker compose -f docker-compose/media.yml ps
View logs:
docker compose -f docker-compose/media.yml logs -f plex
Updating Services
Pull latest images:
docker compose -f docker-compose/media.yml pull
Update a specific service:
docker compose -f docker-compose/media.yml pull plex
docker compose -f docker-compose/media.yml up -d plex
Networks
All services connect to a shared bridge network called homelab-network. Create it once:
docker network create homelab-network
Some services may use additional networks for security isolation:
monitoring-network- For monitoring stackdatabase-network- For database isolationmedia-network- For media services
Create them as needed:
docker network create monitoring-network
docker network create database-network
docker network create media-network
Environment Variables
Create a .env file in the root of your homelab directory with common variables:
# .env
PUID=1000
PGID=1000
TZ=America/New_York
USERDIR=/home/username/homelab
DATADIR=/mnt/data
Never commit .env files to git! Use .env.example as a template instead.
Labels
To enable Authelia SSO
Traefik routing labels
If Traekif is on the same server add these labels.
If Traefik is on a seperate server, don't use traekfik labels in compose files, use an external host yaml file.
Sablier middleware labels
Add these labels to enable ondemand functionality.
labels:
- sablier.enable=true
- sablier.group=<server>-<service name>
- sablier.start-on-demand=true
Best Practices
- Pin Versions: Always specify image versions (e.g.,
nginx:1.25.3notnginx:latest) - Use Labels: Add labels for organization and documentation
- Health Checks: Define health checks for critical services
- Resource Limits: Set memory and CPU limits for resource-intensive services
- Logging: Configure log rotation to prevent disk space issues
- Restart Policies: Use
unless-stoppedfor most services - Comments: Document non-obvious configurations
Template
When creating a new service, use this template:
services:
service-name:
image: vendor/image:version
container_name: service-name
restart: unless-stopped
networks:
- homelab-network
ports:
- "host_port:container_port"
volumes:
- ./config/service-name:/config
- service-data:/data
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:port/health"]
interval: 30s
timeout: 10s
retries: 3
labels:
- "homelab.category=category"
- "homelab.description=Service description"
volumes:
service-data:
driver: local
networks:
homelab-network:
external: true
Troubleshooting
Service won't start
- Check logs:
docker compose -f file.yml logs service-name - Validate config:
docker compose -f file.yml config - Check for port conflicts:
sudo netstat -tlnp | grep PORT - Verify volumes exist and have correct permissions
Permission errors
- Ensure PUID and PGID match your user:
id -uandid -g - Fix directory ownership:
sudo chown -R 1000:1000 ./config/service-name
Network issues
- Verify network exists:
docker network ls - Check service is connected:
docker network inspect homelab-network - Test connectivity:
docker compose exec service1 ping service2
Migration from Docker Run
If you have services running via docker run, migrate them to compose:
-
Get current configuration:
docker inspect container-name > container-config.json -
Convert to compose format (extract image, ports, volumes, environment)
-
Test the compose configuration
-
Stop old container:
docker stop container-name docker rm container-name -
Start with compose:
docker compose -f file.yml up -d
Backup Strategy
Regular backups are essential:
# Backup compose files (already in git)
git add docker-compose/*.yml
git commit -m "Update compose configurations"
# Backup volumes
docker run --rm \
-v volume-name:/data \
-v $(pwd)/backups:/backup \
busybox tar czf /backup/volume-name-$(date +%Y%m%d).tar.gz /data
# Backup config directories
tar czf backups/config-$(date +%Y%m%d).tar.gz config/
Getting Help
- Check the Docker Guidelines for detailed documentation
- Review the GitHub Copilot Instructions for AI assistance
- Consult service-specific documentation in
config/service-name/README.md
Examples
See the example compose files in this directory:
infrastructure.yml- Essential services like reverse proxymedia.yml- Media server stackmonitoring.yml- Observability and monitoringdevelopment.yml- Development environments and tools