Docker Compose homelab with two entrypoints.
docker-compose.ymlruns the main stack.docker-compose.pods.ymlboots Dockhand as the separate control plane.
This repo defaults to local HTTPS routing through Traefik at https://<service>.localhost.me using mkcert-generated local certificates. Production ACME certificates are handled by the alternate Cloudflare DNS-01 Traefik config.
Start the bootstrap control plane first. This works without touching the main stack.
# 1. Clone the repo
$ git clone https://github.com/jakob1379/homelab.git && cd homelab
Cloning into 'homelab'...
done.
# 2. Start the separate Dockhand stack
$ docker compose -f docker-compose.pods.yml up -d
[+] Running 1/1
✔ Container homelab-pods-dockhand-1 Started
# 3. Verify the direct bootstrap endpoint
$ curl -I http://localhost:3000
HTTP/1.1 200 OKOpen http://localhost:3000.
If you want the full routed stack, keep going.
setup-dev.sh is the local source of truth for required variables and generated development keys.
# 1. Prepare .env from .env.example when needed
$ ./setup-dev.sh
[INFO] Setting up the homelab development environment...
[INFO] setup-dev.sh generates local TLS files and app keys, sets local OpenVPN and DumbAssets placeholders, and leaves optional service env overrides optional
[INFO] Set development placeholder: OPENVPN_USER
[INFO] Set development placeholder: OPENVPN_PASSWORD
[INFO] Set development placeholder: DUMBASSETS_PIN
[INFO] Generated development key: NEXTAUTH_SECRET
[INFO] Generated development key: MEILI_MASTER_KEY
[INFO] Generated development key: DUMBASSETS_SESSION_SECRET
[WARN] Missing required variables for docker compose --profile dev:
- PAPERLESS_ADMIN_PASSWORD
...
[INFO] Setup complete!setup-dev.sh writes dummy OpenVPN and DumbAssets PIN values so the local full stack can render. Replace the OpenVPN values and set GLUETUN_HEALTHCHECK_DISABLED=false before running the VPN-backed media automation for real. DUMBASSETS_SESSION_SECRET is generated with the other app keys.
Fill the values you actually need, then start the full stack or the profiles you want.
# 2. Add the required values to .env
$ cat >> .env <<'EOF'
PAPERLESS_ADMIN_PASSWORD=change-me
EOF
# 3. Start the full local stack and wait for health checks
$ docker compose --profile dev up --wait
[+] Running ...
✔ Container homelab-traefik-1 Started
✔ Container homelab-sablier-1 Started
✔ Container homelab-rustfs-1 Started
# 4. Verify a routed endpoint
$ curl https://whoami.localhost.me
Hostname: homelab-whoami-1
IP: 172.20.0.2!!! note
Use service subdomains such as https://whoami.localhost.me or https://traefik.localhost.me. A request to plain https://localhost.me will not match a Traefik router.
This file includes the active stack definitions under services/ plus home-assistant/docker-compose.yml.
include:
- services/networking.yml
- services/rustfs.yml
- services/tools.yml
- services/omni-tools.yml
- services/speedtest-tracker.yml
- services/vert.yml
- services/anythingllm.yml
- services/listmonk.yml
- services/karakeep.yml
- services/immich.yml
- services/paperless-ngx.yml
- services/dumbassets.yml
- services/media.yml
- services/hermes.yml
- services/homepage.yml
- home-assistant/docker-compose.ymlThis file includes only services/pods.yml.
include:
- services/pods.yml| Profile | Purpose |
|---|---|
dev |
Full main stack with local mkcert-backed Traefik HTTPS |
prod |
Full main stack with Cloudflare DNS-01 ACME Traefik HTTPS |
infra |
Always-on foundation services |
apps |
Most application services |
tunnel |
Optional cftunnel sidecar for Listmonk |
service |
Narrow profile currently used by Home Assistant |
Use exactly one full-stack profile at a time: dev or prod.
home-assistant/docker-compose.yml puts ha in profiles: [apps, service, dev, prod].
The routing model is split.
These are the routes that currently use explicit Traefik file-provider config, usually because they also need Sablier middleware:
- AnythingLLM
- BentoPDF
- CloudBeaver
- DumbAssets
- Homepage
- Home Assistant
- Immich Power Tools
- IT Tools
- Jellyfin
- Karakeep
- Listmonk
- NetAlertX
- Omni Tools
- Paperless-ngx
- RustFS
- Seerr
- Speedtest Tracker
- VERT
- whoami
These are currently routed with service labels instead of config/traefik/dyn/*.yml:
- AdGuard
- Dockhand
- Hermes
- Immich
- Prowlarr
- Bazarr
- Radarr
- Sonarr
- torrent (
https://torrent.${DOMAIN}) - Traefik dashboard
- Sablier-managed:
anythingllm,bentopdf,cbeaver,dumbassets,home,immich-power-tools,ittools,keep,omni-tools,paperless,seerr,speedtest-tracker,vert,whoami - Always on / not wired to Sablier middleware:
traefik,sablier,rustfs,adguard,netalertx,dockhand,immich,home-assistant,hermes,jellyfin,torrent,sonarr,radarr,prowlarr,bazarr - Important exception:
listmonkstill hassablier.*labels, butconfig/traefik/dyn/listmonk.ymldoes not attach a Sablier middleware. Treat it as not sleeping on request in the current repo.
- Traefik
- Sablier
- RustFS
- AdGuard Home
- NetAlertX
- whoami
- Homepage
- AnythingLLM
- IT Tools
- CloudBeaver
- BentoPDF
- DumbAssets
- Omni Tools
- VERT
- Speedtest Tracker
- Hermes
- Karakeep +
chrome+meilisearch - Listmonk +
listmonk-postgres+ optionalcftunnel - Immich +
immich-postgres+redis+ workers - Paperless-ngx + PostgreSQL + Redis + Gotenberg + Tika
- Media:
jellyfin,seerr,immich-power-tools,torrent,sonarr,radarr,flaresolverr,byparr,prowlarr,bazarr - Home Assistant
Local development uses config/traefik/traefik.yml with HTTPS on websecure.
Run setup-dev.sh to create the mkcert-backed files for
https://*.localhost.me, then start the stack with:
docker compose --profile dev up --waitFor production ACME certificates, start the stack with the production profile:
docker compose --profile prod up -dDOMAINACME_EMAILCF_DNS_API_TOKEN
services/media.yml runs Gluetun as the shared network namespace for:
torrentsonarrradarrflaresolverrbyparr
prowlarr and bazarr route directly on traefik_public.
The active compose config requires OPENVPN_USER and OPENVPN_PASSWORD for Gluetun. setup-dev.sh supplies local dummy values so config rendering works, but real media downloads need real VPN credentials.
These files exist but are not included from docker-compose.yml:
services/teable.ymlservices/teable-migrate.yml
- Docs index
- Architecture
- Service reference
- Customization
- Deploy through Dockhand
- Troubleshooting
- Queue-driven sleep status
MIT. See LICENSE.