Self-Host Traefik: The Ultimate Reverse Proxy in 15 Minutes
Every self-hosted application needs a front door. Whether you're running a dozen Docker containers or just getting started with your first homelab, you need a reverse proxy that handles routing, SSL certificates, and load balancing — without the headache of manual configuration.
Enter Traefik: a cloud-native edge router that automatically discovers your services and configures itself. No more editing Nginx config files every time you spin up a new container. Traefik watches your Docker socket, reads labels, and handles HTTPS certificates via Let's Encrypt — automatically.
In this guide, you'll deploy Traefik with Docker Compose, secure it with SSL, and route traffic to multiple services — all in under 15 minutes.
What Problem Does Traefik Solve?
Traditional reverse proxies like Nginx or Apache require manual configuration files for every backend service. Add a new app? Edit the config. Remove one? Edit again. Miss a semicolon? Debug for 20 minutes.
Traefik eliminates this friction by:
- Auto-discovering services via Docker labels
- Automatically requesting and renewing SSL certificates via Let's Encrypt
- Supporting multiple entry points (HTTP, HTTPS, TCP, UDP)
- Providing a built-in dashboard for monitoring routes and services
- Handling middleware for authentication, rate limiting, redirects, and more
If you're running a Docker-based stack, Traefik is the single best investment of your time.
Prerequisites
- A VPS or server with Docker and Docker Compose installed
- A domain name pointed to your server (e.g.,
traefik.yourdomain.com) - Ports 80 and 443 open on your firewall
- Basic familiarity with Docker Compose
Recommended specs: 1 CPU, 512MB RAM minimum. Traefik is lightweight.
Step 1: Create the Docker Network
Traefik and your services need to communicate on a shared Docker network. Create it once:
docker network create traefik-public
Step 2: Prepare the Directory Structure
mkdir -p ~/traefik/{data,letsencrypt}
touch ~/traefik/letsencrypt/acme.json
chmod 600 ~/traefik/letsencrypt/acme.json
The acme.json file stores your Let's Encrypt certificates. It must be readable only by Traefik.
Step 3: Docker Compose Configuration
Create ~/traefik/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"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
- ./data/traefik.yml:/traefik.yml:ro
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.middlewares=auth@file"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
networks:
traefik-public:
external: true
Step 4: Traefik Static Configuration
Create ~/traefik/data/traefik.yml:
global:
checkNewVersion: false
sendAnonymousUsage: false
api:
dashboard: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /letsencrypt/acme.json
tlsChallenge: {}
providers:
docker:
exposedByDefault: false
network: traefik-public
file:
directory: /data/dynamic
watch: true
log:
level: INFO
accessLog: {}
This config:
- Redirects all HTTP to HTTPS
- Enables the dashboard
- Configures Let's Encrypt with TLS challenge
- Watches Docker for labeled containers
Step 5: Basic Auth Middleware (Optional but Recommended)
Protect your dashboard with HTTP Basic Auth. Create the password hash:
# Install apache2-utils if needed
htpasswd -nb admin your_secure_password | sed -e s/\$/\$\$/g
Create ~/traefik/data/dynamic/auth.yml:
http:
middlewares:
auth:
basicAuth:
users:
- "admin:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
Replace the hash with your own generated value.
Step 6: Deploy Traefik
cd ~/traefik
docker compose up -d
Check the logs:
docker compose logs -f traefik
Step 7: Verify the Setup
- Dashboard: Visit
https://traefik.yourdomain.com— you should see the Traefik dashboard after authenticating. - SSL Certificate: Check that your browser shows a valid Let's Encrypt certificate.
- HTTP Redirect: Visit
http://traefik.yourdomain.com— it should redirect to HTTPS.
Step 8: Route Your First Service
Here's the magic. To expose any Docker container through Traefik, just add labels:
services:
whoami:
image: traefik/whoami
container_name: whoami
networks:
- traefik-public
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:
traefik-public:
external: true
Deploy it, point whoami.yourdomain.com to your server, and Traefik handles the rest — SSL, routing, the works.
Next Steps
- Add rate limiting: Use
traefik.http.middlewares.ratelimit.ratelimit.average=100 - Enable compression: Add the
compressmiddleware - Forward Auth: Integrate with Authelia or Authentik for SSO
- Monitor Traefik: Enable Prometheus metrics and visualize in Grafana
- TCP/UDP routing: Route non-HTTP traffic like databases or game servers
Related Guides
- Self-Host Portainer: Manage All Your Docker Containers in 15 Minutes
- Self-Host Uptime Kuma: Monitor Everything in 15 Minutes
- Self-Host Authelia: Add SSO to All Your Apps (coming soon)
- Self-Host Grafana: Visualize Your Infrastructure (coming soon)
Traefik transforms your Docker stack from a collection of containers into a production-ready platform. Once it's running, adding new services is as simple as adding a few labels — no config restarts, no certificate management, no friction.
Questions or stuck on a step? Drop a comment below.