Self-Hosted Services¶
Containerized applications for your homelab infrastructure.
Service Categories¶
Infrastructure¶
| Service | Description |
|---|---|
| Reverse Proxy | Route traffic to services (Traefik, Caddy) |
| SSL/TLS Certificates | Certificate management and HTTPS |
| Authentication | SSO and identity management |
| Pi-hole | Network-wide ad blocking |
Applications¶
| Service | Description |
|---|---|
| Media Stack | Jellyfin and *arr automation |
| Homepage | Homelab dashboard |
Monitoring¶
| Service | Description |
|---|---|
| Uptime Kuma | Status pages and monitoring |
Deployment Patterns¶
Recommended Stack¶
Internet
│
v
┌─────────────────┐
│ Reverse Proxy │ (Traefik/Caddy)
│ + SSL/TLS │
└─────────────────┘
│
├──> Authentication (Authentik)
│
├──> Applications
│ ├── Jellyfin
│ ├── Homepage
│ └── Other services
│
└──> Monitoring
├── Uptime Kuma
└── Prometheus/Grafana
DNS: Pi-hole (network-wide)
Docker Network Setup¶
# Create shared network
networks:
proxy:
external: true
# In each service's docker-compose.yml
services:
myservice:
networks:
- proxy
- default
networks:
proxy:
external: true
Port Map¶
Canonical host-port assignments for this build. Most services should be routed through the reverse proxy on 80/443 and not exposed on the LAN — services below that bind to a LAN port are either ones the reverse proxy can't proxy easily (DNS, BitTorrent peer port) or admin/legacy access points.
| Port | Service | Notes |
|---|---|---|
| 53/tcp, 53/udp | Pi-hole DNS | LAN |
| 80, 443 | Traefik / Caddy | LAN; everything else routes through here |
| 3000 | Grafana | bind 127.0.0.1 only |
| 3001 | Uptime Kuma | bind 127.0.0.1 only |
| 3030 | Homepage | bind 127.0.0.1 only (Grafana takes 3000) |
| 5432 | Postgres (Authentik, etc.) | bind 127.0.0.1 only |
| 7878 | Radarr | bind 127.0.0.1; behind reverse proxy |
| 8080 | cAdvisor | bind 127.0.0.1; metrics scrape only |
| 8096 | Jellyfin | LAN (local clients) |
| 8181 | Tautulli | bind 127.0.0.1 |
| 8989 | Sonarr | bind 127.0.0.1; behind reverse proxy |
| 9000 | Portainer (if used) | bind 127.0.0.1 |
| 9090 | Prometheus | bind 127.0.0.1 |
| 9091 | Transmission web UI | bind 127.0.0.1 (Authelia also defaults here — Authelia is behind the reverse proxy on its own subdomain) |
| 9696 | Prowlarr | bind 127.0.0.1 |
| 11434 | Ollama | LAN or Tailscale-only |
| 32400 | Plex | LAN |
| 51413/tcp, 51413/udp | Transmission peer | LAN/WAN as needed |
Bind sensitive services to 127.0.0.1 in compose like this:
…and add the corresponding Traefik / Caddy route so users hit grafana.example.com via 80/443 instead of :3000.
Common Configurations¶
Environment Variables¶
Volume Permissions¶
Resource Limits¶
Getting Started¶
- Set up Reverse Proxy first
- Configure Authentication for SSO
- Deploy services as needed
- Add Homepage dashboard
- Set up Uptime Kuma monitoring