Traefik + Docker Compose: Automatic HTTPS for Every Service
Set up Traefik as a reverse proxy with Docker Compose and get automatic Let's Encrypt HTTPS certificates for every service on your homelab.
Running multiple Docker services on the same machine means dealing with ports: Nextcloud on 8080, Vaultwarden on 8081, Jellyfin on 8096. Remembering port numbers is annoying, but worse, most services require HTTPS to work correctly — and getting a certificate for each service individually is a pain.
Traefik solves both problems. It watches your Docker containers automatically, routes traffic based on labels in your Compose files, and provisions Let’s Encrypt certificates without any manual intervention.
This guide sets up a working Traefik installation that you can use as the front door for everything else on your homelab.
Prerequisites
- Docker and Docker Compose installed
- A domain name pointed at your server’s public IP (A record)
- Port 80 and 443 open on your firewall/router
If you’re running on a local-only network without a public domain, use a wildcard DNS service (like nip.io) or self-signed certificates instead. This guide focuses on the public HTTPS path.
Architecture
Traefik runs as a container on a Docker network shared with your other services. When you start a new service container with the right labels, Traefik detects it automatically via the Docker socket and starts routing traffic to it.
Internet → Port 443 → Traefik → your-service.yourdomain.com → service container
Step 1: Create the Traefik Network
All services that Traefik will proxy need to be on a shared network. Create it once:
docker network create traefik-proxy
Step 2: Create the Traefik Configuration Directory
mkdir -p ~/services/traefik
cd ~/services/traefik
touch acme.json
chmod 600 acme.json
The acme.json file stores your Let’s Encrypt certificates. The chmod 600 is required — Traefik will refuse to start if the file has looser permissions.
Step 3: Write the Traefik Compose File
Create ~/services/traefik/docker-compose.yml:
services:
traefik:
image: traefik:v3
container_name: traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme.json:/acme.json
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=you@yourdomain.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/acme.json"
networks:
- traefik-proxy
networks:
traefik-proxy:
external: true
Replace [email protected] with your actual email. Let’s Encrypt uses it for expiry notifications.
Key flags:
providers.docker.exposedbydefault=false— Traefik only routes to containers that explicitly opt in with a label. Without this, every container would get a route.- The redirect from port 80 to 443 is built in via the entrypoint configuration.
Step 4: Start Traefik
docker compose up -d
Check that it started:
docker compose logs -f
You should see Traefik start up and detect the Docker provider. No certificate activity yet — that happens when a service requests one.
Step 5: Add Traefik Labels to a Service
Here’s how to set up Vaultwarden behind Traefik. Create ~/services/vaultwarden/docker-compose.yml:
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
volumes:
- ./data:/data
environment:
- WEBSOCKET_ENABLED=true
labels:
- "traefik.enable=true"
- "traefik.http.routers.vaultwarden.rule=Host(`vault.yourdomain.com`)"
- "traefik.http.routers.vaultwarden.entrypoints=websecure"
- "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"
- "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
networks:
- traefik-proxy
networks:
traefik-proxy:
external: true
Note: no ports: section — Traefik handles the routing. The container is only reachable via Traefik.
Start it:
docker compose up -d
Traefik detects the new container via the Docker socket, reads the labels, and starts routing vault.yourdomain.com to the Vaultwarden container. It requests a certificate from Let’s Encrypt on first access — expect a few seconds delay the first time.
Step 6: Verify
Navigate to https://vault.yourdomain.com. You should see:
- A valid HTTPS certificate (browser padlock)
- The Vaultwarden web vault
If it doesn’t work, check:
# Traefik logs
docker logs traefik -f
# Verify the container is on the traefik-proxy network
docker inspect vaultwarden | grep -A 5 Networks
Adding More Services
Every additional service follows the same pattern: add the traefik-proxy network, add four labels (enable, rule, entrypoints, tls), remove the ports: section. No changes to Traefik itself.
For services that listen on a non-80 port inside the container, set the loadbalancer.server.port label accordingly. For example, Jellyfin listens on port 8096 inside its container:
labels:
- "traefik.enable=true"
- "traefik.http.routers.jellyfin.rule=Host(`media.yourdomain.com`)"
- "traefik.http.routers.jellyfin.entrypoints=websecure"
- "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt"
- "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
Traefik Dashboard
Traefik includes a read-only dashboard showing all detected routers, services, and certificates. Add this to the Traefik command list to enable it:
- "--api.dashboard=true"
Then add a router to expose it:
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"
Restrict access to the dashboard — it exposes your routing configuration. Adding basic auth middleware or IP allowlisting is recommended before exposing it.
Related
Docker Compose Networking: Bridge, Host, and Custom Networks Explained
Understand Docker Compose networking — how containers find each other, how to isolate services, and how to expose only what needs exposing.
Portainer: The Best GUI for Managing Docker on Your Homelab
Install and configure Portainer CE to manage Docker containers, images, networks, and volumes through a browser-based dashboard — no command line required.
Best Docker Compose Apps for Your Homelab in 2026
The 20 best services to run in Docker on your home server, with ready-to-use Compose snippets and honest assessments of setup complexity and ongoing maintenance.