Traefik
Last updated on 07 January 2025
Most of my personal services I run within my Tailscale network, and so I do not tend to bother with HTTPS (since provisioning TLS certificates for multiple services running on a single host via Tailscale is a pain).
However, for external services that need to be accessed publicly, I use Traefik [1] as a reverse proxy and for managing and provisioning TLS certificates.
Running Traefik
Run Traefik using Docker. Create a `docker-compose.yml` file in a directory called `traefik`:
services:
reverse-proxy:
image: traefik:v2.6
container_name: traefik
command:
- "--providers.docker"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.email=CHANGEME"
- "--certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme/acme.json"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
volumes:
- ./acme:/etc/traefik/acme # To persist certificate info
- /var/run/docker.sock:/var/run/docker.sock # To access the host Docker daemon
networks:
- net
restart: always
networks:
net:
driver: bridge
Rate-limiting
Sometimes it is useful to rate-limit access to services via Traefik. For example, I recently experienced bots scraping my Gitea instance, causing the host to be partially overloaded.
Rate-limit rules can be set using standard Traefik labels in the compose definition for the relevant service. For example, in my Gitea `docker-compose.yml` file:
... - traefik.http.routers.gitea.middlewares=gitea-ratelimit - traefik.http.middlewares.gitea-ratelimit.ratelimit.average=2 - traefik.http.middlewares.gitea-ratelimit.ratelimit.period=1s - traefik.http.middlewares.gitea-ratelimit.ratelimit.burst=5
The bridge network
This setup creates a bridge network into which we will add other services. This allows Traefik to route traffic to them.
The directory name (`traefik`) is important (in my case) since my services rely on the fact that the network created is called `traefik_net`.
Adding other services
When adding other services, follow these steps:
1. Set-up DNS such that your chosen domain name points to the server
1. Create a `docker-compose.yml` for the service with Traefik labels (see below)
1. Bring up the service
An example `docker-compose.yml` for a Traefik-connected service:
services:
example:
image: example
networks:
- traefik_net
labels:
- traefik.http.routers.servicename.rule=Host(`domain.com`)
- traefik.http.routers.servicename.tls=true
- traefik.http.routers.servicename.tls.certresolver=myresolver
networks:
traefik_net:
external: true
Change `domain.com` to the real domain (or subdomain) and change `servicename` to a unique name in your Traefik network.
When you bring the service up, Traefik will detect it and then auto-provision and renew the TLS certificates.