How to Install Traefik with Docker Compose
Table of contents
- Key takeaways
- What does Traefik do as a reverse proxy?
- Prerequisites
- Prepare the directory structure
- Configure Traefik (traefik.yml)
- Generate dashboard credentials
- Create the Docker network and docker-compose.yml
- Start Traefik
- Frequently asked questions
- Is Let's Encrypt required with Traefik?
- Does Traefik work the same way on Kubernetes as on Docker Compose?
- What happens if I lose the acme.json file?
- Conclusion
- Sources
Updated: 2026-07-07
Learn how to install Traefik with Docker Compose – a modern reverse proxy with automatic Docker service discovery and free SSL certificates via Let's Encrypt.
Traefik[1] is a reverse proxy and edge router designed for container environments. Unlike solutions such as nginx or HAProxy that require manual configuration reloads, Traefik automatically discovers Docker services via labels and handles SSL certificate acquisition and renewal with Let’s Encrypt[2] automatically. This article explains how to deploy it with Docker Compose.
Key takeaways
-
Traefik automatically discovers Docker services: no configuration reload is needed when adding new containers.
-
SSL certificate management with Let’s Encrypt is fully automatic: request, renewal, and storage without manual intervention.
-
Traefik’s dashboard has no built-in authentication; protecting it with HTTP Basic Auth before exposing it is mandatory.
-
Communication between Traefik and services goes through a dedicated Docker virtual network.
What does Traefik do as a reverse proxy?
A reverse proxy receives external requests and routes them to the correct internal service. Traefik adds on top of this basic role:
-
Automatic discovery: reads Docker labels in real time and updates its routing table without restarts.
-
Automatic TLS: negotiates certificates with Let’s Encrypt via HTTP-01 or DNS-01 challenge.
-
Middleware: redirects, basic auth, rate limiting, and security headers configurable per label.
-
Web dashboard: visual interface for inspecting active routers, services, and certificates.
Reverse proxy diagram: client connects to the proxy which forwards the request to the appropriate internal server
Prerequisites
-
A domain with DNS records pointing to the server.
Prepare the directory structure
Create the working directory, the acme.json file for storing certificates, and Traefik’s static configuration file:
mkdir -p docker/traefik/traefik-data
touch docker/traefik/traefik-data/acme.json
chmod 600 docker/traefik/traefik-data/acme.json
nano docker/traefik/traefik-data/traefik.yml
The 600 permission on acme.json is mandatory: Traefik rejects the file if other users have read access.
Configure Traefik (traefik.yml)
Inside traefik.yml we add the static configuration. Change the email address so Let’s Encrypt can send certificate expiry warnings:
api:
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
http:
acme:
email: your@email.com
storage: acme.json
httpChallenge:
entryPoint: http
With exposedByDefault: false, Traefik only routes to containers that explicitly have the traefik.enable=true label. This prevents accidentally exposing internal services.
Generate dashboard credentials
Traefik’s dashboard has no built-in authentication, so we must protect it with Basic Auth. Generate the password hash using htpasswd:
sudo apt-get install apache2-utils
echo $(htpasswd -nb USER PASSWORD) | sed -e s/$/$$/g
The double escaping of $ ($$) is necessary because Docker Compose interprets $ as the start of an environment variable in YAML files.
Create the Docker network and docker-compose.yml
Create the dedicated virtual network for Traefik:
docker network create traefik-proxy
cd docker/traefik
nano docker-compose.yml
Contents of docker-compose.yml. Replace USER:HASH, traefik.example.com, and the email with your own values:
version: '3'
services:
traefik:
image: traefik:v2.4.2
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- traefik-proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik-data/traefik.yml:/traefik.yml:ro
- ./traefik-data/acme.json:/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD_HASH"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=http"
- "traefik.http.routers.traefik-secure.service=api@internal"
networks:
traefik-proxy:
external: true
The version: '3' key in this file is purely informational: Docker Compose’s official documentation[3] has marked it obsolete for several versions now, since Compose always validates against the latest schema regardless of the value given. It’s kept here because it’s the format this guide was tested with alongside the traefik:v2.4.2 image.
Let’s Encrypt logo, the free certificate authority integrated in Traefik for automatic TLS management
Start Traefik
Start the container in detached mode:
docker-compose up -d
Access the dashboard from your browser:
https://traefik.example.com/
The dashboard will show active routers, services, and certificates. To add a new service to the stack, simply add the appropriate traefik.* labels to the container: Traefik detects it automatically without restarts.
For more detail on Docker service management, the post on Docker Compose on Ubuntu 20.04 covers the full orchestration workflow.
Frequently asked questions
Is Let’s Encrypt required with Traefik?
No. Let’s Encrypt is the simplest option because Traefik integrates it natively via certificatesResolvers, but the ACME provider is configurable: you can point it at another certificate authority that supports the ACME protocol, or disable the resolver and import your own certificates as static files.
Does Traefik work the same way on Kubernetes as on Docker Compose?
The concept is the same (automatic discovery and dynamic routing), but the provider changes: instead of reading Docker container labels, on Kubernetes Traefik reads IngressRoute resources or the cluster’s standard Ingress/Gateway API. The static configuration in traefik.yml (entryPoints, certificatesResolvers) is practically identical in both cases.
What happens if I lose the acme.json file?
Traefik automatically requests new certificates from Let’s Encrypt the next time it starts, as long as the domain still points to the server. It isn’t a catastrophic failure, but keep in mind that Let’s Encrypt enforces per-domain rate limits, so losing and regenerating acme.json too often in production can temporarily exhaust them.
Conclusion
Traefik eliminates the operational friction of the reverse proxy in Docker environments: automatic discovery, managed certificates, and label-based routing let you publish new services in seconds. The key to a secure configuration is protecting the dashboard with Basic Auth and never exposing services without the traefik.enable=true label.
Read the Spanish version of this article: Cómo instalar Traefik con Docker Compose.