--- title: Traefik description: Hypercharged reverse proxy with Docker autodiscovery and other goodies published: true date: 2019-12-28T17:37:38.426Z tags: --- # What is this? Traefik hogs your ports `80` and `443` (and others), will intercept HTTP requests to your server and forward them to different endpoints. It allows you to run multiple web services on the same IP address and access them on a domain name basis. We use both the Docker backend and a manual routing backend. # Requirements To make it easier to have multiple `docker-compose.yml` without having to specify networks by hand, we use Traefik natively installed on the host, rather than the usual Docker install. This allows it to access all Docker networks by default. On NixOS: ``` traefik = { enable = true; group = "docker"; configFile = "/var/lib/traefik/traefik.toml"; }; ``` Using docker-compose: ``` version: '3.7' services: traefik: image: traefik:latest network_mode: host volumes: - ./config/:/etc/traefik/ - /var/run/docker.sock:/var/run/docker.sock ``` # Traefik Configuration Paths vary between a docker-compose install or a NixOS install. The container wants its files placed at `/etc/traefik/` while a native install is most likely to prefer `/var/lib/traefik/`. Paths provided in this example use the `/etc/traefik/` route. An `acme` folder needs to exist with `700` permissions, inside there should be an `acme.json` with 600 permissions. Without them, Let's Encrypt certificates will never work. ## Static configuration Changing this requires a Traefik restart. `/etc/traefik/traefik.yml` ``` api: dashboard: true entryPoints: web: address: ":80" web-secure: address: ":443" providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false file: filename: /etc/traefik/config.yml watch: true certificatesResolvers: default: acme: email: example@changeme.com storage: /etc/traefik/acme/acme.json tlsChallenge: {} log: level: WARNING filePath: /etc/traefik/debug.log format: json ``` ## Dynamic configuration Traefik live reloads this file. All http input is elevated to https using the "redirect" middleware. `traefik` and `netdata` routers listen on 443. `traefik` also runs the "auth" middleware to ask for password. `/etc/traefik/config.yml` ``` http: routers: redirector: rule: HostRegexp(`{any:.*}`) entryPoints: - "web" service: dummy middlewares: - redirect traefik: rule: Host(`traefik.your.domain`) entryPoints: - "web-secure" service: api@internal middlewares: - auth tls: certResolver: default netdata: rule: Host(`netdata.your.domain`) entryPoints: - "web-secure" service: netdata tls: certResolver: default services: dummy: loadBalancer: servers: - url: http://127.0.0.1 netdata: loadBalancer: servers: - url: http://localhost:19999 middlewares: redirect: redirectScheme: scheme: https auth: basicAuth: users: - 'test:$apr1$tyoqkxlc$BbG4rHVMcV7mSQWIgEZQT0' #test/test tls: options: default: sniStrict: true minVersion: VersionTLS12 cipherSuites: - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 mintls13: minVersion: VersionTLS13 ``` # Configuring a docker-compose Service This is the most usual configuration a service will need, which is self explanatory. ``` version: '3.7' services: whoami: image: containous/whoami labels: - traefik.enable=true - traefik.http.routers.whoami.entryPoints=web-secure - traefik.http.routers.whoami.rule=Host(`whoami.your.domain`) - traefik.http.routers.whoami.tls.certresolver=default ``` A more verbose one is needed when a specific port must be used or a middleware is needed, such as asking for basic authentication. Here shown a Caddy download page that asks for the username and password defined in the dynamic configuration. It also doesn't use Let's Encrypt and will serve Traefik's default certificate, as the machine this configuration is pulled from is running behind Cloudflare. ``` version: '3.7' services: private-caddy: image: abiosoft/caddy:php restart: unless-stopped volumes: - ./srv:/srv labels: - traefik.enable=true - traefik.http.routers.private-caddy.entryPoints=web-secure - traefik.http.routers.private-caddy.rule=Host(`private.your.domain`) - traefik.http.routers.private-caddy.tls=true - traefik.http.routers.private-caddy.middlewares=auth@file - traefik.http.services.private-caddy.loadbalancer.server.port=2015 ```