Self-Host Traefik: The Ultimate Reverse Proxy for Your Homelab in 20 Minutes
Every self-hosted stack eventually hits the same wall: you've got a dozen services running on different ports, and you're memorizing IP addresses like it's 1998. Traefik solves this. It's a modern reverse proxy that automatically discovers your Docker containers, handles SSL certificates, and routes traffic — all with minimal configuration.
Why Traefik over Nginx or Caddy? Traefik's killer feature is automatic service discovery. Point it at your Docker socket, label your containers, and it just works. No config file edits every time you spin up a new service. Plus, built-in Let's Encrypt support means SSL is handled automatically.
What You'll Build
- Traefik 3.x running in Docker
- Automatic SSL certificates via Let's Encrypt
- Dashboard secured with basic auth
- Reverse proxy routing for any container
Prerequisites
- A VPS or server with Docker and Docker Compose installed
- A domain name pointed to your server (A record)
- Ports 80 and 443 open
- 5 minutes of actual work, 15 minutes of waiting for SSL
Step 1: Create the Docker Compose File
Create a directory for Traefik and add your configuration:
mkdir -p ~/traefik && cd ~/traefik
Create docker-compose.yml:
version: "3.8"
services:
traefik:
image: traefik:v3.1
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
ports:
- "80:80"
- "443:443"
environment:
- [email protected] # If using Cloudflare
- CF_API_KEY=your-cloudflare-api-key # If using Cloudflare
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- ./acme.json:/acme.json
- ./config:/config:ro
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:$$2y$$05$$rWvTueXNlWvTueXNlWvTueXNlWvTueXNlWvTueXNlWvTueXNlWvTue"
networks:
proxy:
external: true
Step 2: Create the Static Configuration
Create traefik.yml:
api:
dashboard: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: proxy
file:
directory: /config
watch: true
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /acme.json
httpChallenge:
entryPoint: web
Create the ACME storage file and set permissions:
touch acme.json && chmod 600 acme.json
Step 3: Create the Docker Network
docker network create proxy
Step 4: Launch Traefik
docker compose up -d
Check the logs to make sure it's running:
docker logs traefik
Step 5: Route a Container Through Traefik
Here's the magic. Add labels to any container you want to expose:
version: "3.8"
services:
whoami:
image: traefik/whoami
container_name: whoami
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
proxy:
external: true
Spin it up:
docker compose up -d
Traefik automatically detects the container, requests an SSL certificate, and routes traffic. No restart, no config reload.
Verification
- Visit
https://traefik.yourdomain.com— you should see the dashboard (after basic auth) - Visit
https://whoami.yourdomain.com— you should see the whoami service response - Check certificate:
openssl s_client -connect whoami.yourdomain.com:443 -servername whoami.yourdomain.com 2>/dev/null | openssl x509 -noout -dates
Pro Tips
- Use middlewares: Add rate limiting, IP whitelisting, or forward auth with labels
- Wildcard certificates: Use DNS challenge with Cloudflare for
*.yourdomain.com - Dashboard security: Never expose the dashboard without auth — or better, don't expose it at all and use
docker exec - Health checks: Traefik automatically removes unhealthy containers from rotation
Next Steps
- Add Portainer for container management behind Traefik
- Set up WireGuard for secure remote access to your internal services
- Monitor Traefik logs with Grafana + Prometheus
Traefik is the backbone of a modern homelab. Once it's running, adding new services takes seconds — just add labels and go.