Expose container with Traefik and Docker
Traefik is a great asset when you need to expose Docker containers and configure routing easily.
Traefik uses Docker API to expose ports and labels to configure Traefik routing itself.
All Traefik features can be used:
- Entrypoints
- Routers
- Middlewares
Running Traefik on Docker daemon
Below is the Docker compose definition that runs the Traefik and Whoami containers.
version: "3.3"
services:
traefik:
image: "traefik:v3.1"
container_name: "traefik"
command:
#- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
We can see that labels used on the whoami container are:
traefik.enable=true
traefik.http.routers.whoami.rule=Host(whoami.localhost)
traefik.http.routers.whoami.entrypoints=web
Let's start with the latest. The latest label defines which entrypoint is used - web refers to 80 port and HTTP connections. websecure
refers to the HTTPS connections.
For every container router must be defined with a unique name specified for that container -whoami
in this case.
The router needs a definition of at least one rule but rules can be stacked.
Traefik will route the traffic correctly to the whoami container only if the hostname matches the whoami.localhost
.
The first label enables Traefik to take whoami container into consideration.
TLS: Letsencrypt, Traefik, and Docker
TLS also can be automated via Letsencrypt. This process is automatic which is great. Instead of using nginx and glue scripts to automate the process, Traefik handles this automatically which is a big plus.
Traefik static configuration needs to be configured similarly:
providers:
docker:
exposedByDefault: false
entrypoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: :443
certificatesResolvers:
myresolver:
acme:
tlschallenge: true
email: email@example.com
storage: /SOME_PERSISTENT_LOCATION/acme.json
api:
insecure: true
dashboard: true
Where email@example.com
and /SOME_PERSISTENT_LOCATION/acme.json
needs to be replaced with correct values for the specific environment where Traefik is running.
Next labels need to be applied to the container that needs to be exposed via TLS.
labels:
"traefik.enable": "true"
"traefik.http.routers.service.rule": "Host(`example.com`)"
"traefik.http.routers.service.entrypoints": "websecure"
"traefik.http.routers.service.tls.certresolver": "myresolver"
A few labels configured correctly are all you need to expose containers via Traefik.