Skip to content

Traefik

Martin Skalicky edited this page Aug 4, 2026 · 2 revisions

Traefik

Reverse proxy, která se konfiguruje sama podle štítků kontejnerů. Když ti služby často přibývají a ubývají, ušetří to spoustu ruční práce — a když máš tři stabilní kontejnery, je to zbytečná složitost oproti Caddy.

V čem je jiná

Nemá konfigurační soubor pro jednotlivé weby. Sleduje Docker socket a když se objeví kontejner se správnými štítky, začne ho obsluhovat. Když zmizí, přestane.

Cena za to jsou dvě věci: potřebuje přístup k Docker socketu (což je bezpečnostně citlivé) a terminologie je vlastní — entrypoint, router, service, middleware. Než to jednou pochopíš, chvíli to trvá.

Základní nasazení

compose.yml:

services:
  traefik:
    image: traefik:v3
    restart: unless-stopped
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https
      - --certificatesresolvers.le.acme.email=ty@example.cz
      - --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt
    networks: [web]

volumes:
  letsencrypt:

networks:
  web:

exposedbydefault=false je důležité. Bez něj Traefik zveřejní každý kontejner, který uvidí.

Přidání služby

  immich:
    image: ghcr.io/immich-app/immich-server
    networks: [web]
    labels:
      - traefik.enable=true
      - traefik.http.routers.immich.rule=Host(`foto.example.cz`)
      - traefik.http.routers.immich.entrypoints=websecure
      - traefik.http.routers.immich.tls.certresolver=le
      - traefik.http.services.immich.loadbalancer.server.port=2283

Žádné ports, žádný zásah do konfigurace proxy. Kontejner musí být ve stejné síti jako Traefik.

To loadbalancer.server.port je port uvnitř kontejneru. Traefik jde přímo na něj, publikovaný port nepotřebuje. Souvislosti v sítích v Dockeru.

Slovníček Traefiku

Pojem Co to je
entrypoint port, na kterém Traefik poslouchá (:80, :443)
router pravidlo, co kam patří (podle Host, cesty, hlavičky)
service cíl, kam se to pošle
middleware úprava po cestě (autentizace, hlavičky, přesměrování)
provider odkud se bere konfigurace (Docker, soubor, Kubernetes)

Middleware

Autentizace před službou bez vlastního přihlašování:

labels:
  - traefik.http.middlewares.auth.basicauth.users=martin:$$2y$$10$$hash
  - traefik.http.routers.app.middlewares=auth

V Compose se $ píše jako $$, jinak ho Compose sežere.

Omezení podle IP:

labels:
  - traefik.http.middlewares.jenlan.ipallowlist.sourcerange=192.168.1.0/24,10.10.0.0/24
  - traefik.http.routers.proxmox.middlewares=jenlan

Bezpečnostní hlavičky:

labels:
  - traefik.http.middlewares.sec.headers.stsSeconds=31536000
  - traefik.http.middlewares.sec.headers.contentTypeNosniff=true
  - traefik.http.middlewares.sec.headers.frameDeny=true

Middleware se dají řetězit oddělené čárkou.

Wildcard certifikát

Přes DNS-01, s tokenem od DNS poskytovatele:

    command:
      - --certificatesresolvers.le.acme.dnschallenge=true
      - --certificatesresolvers.le.acme.dnschallenge.provider=cloudflare
    environment:
      - CF_DNS_API_TOKEN=${CF_TOKEN}
labels:
  - traefik.http.routers.app.tls.domains[0].main=example.cz
  - traefik.http.routers.app.tls.domains[0].sans=*.example.cz

Viz certifikáty a Let's Encrypt.

Služby mimo Docker

Pro věci, které v kontejneru neběží (Proxmox, router, NAS), použij souborový provider:

    command:
      - --providers.file.directory=/etc/traefik/dynamic
    volumes:
      - ./dynamic:/etc/traefik/dynamic:ro

dynamic/proxmox.yml:

http:
  routers:
    proxmox:
      rule: "Host(`pve.example.cz`)"
      entrypoints: [websecure]
      service: proxmox
      tls:
        certresolver: le
  services:
    proxmox:
      loadBalancer:
        servers:
          - url: "https://192.168.1.5:8006"
        serversTransport: skipverify
  serversTransports:
    skipverify:
      insecureSkipVerify: true

To insecureSkipVerify je nutné, protože Proxmox má certifikát podepsaný sám sebou.

Dashboard

    command:
      - --api.dashboard=true
    labels:
      - traefik.http.routers.dash.rule=Host(`traefik.example.cz`)
      - traefik.http.routers.dash.service=api@internal
      - traefik.http.routers.dash.middlewares=auth,jenlan

Dashboard je užitečný při ladění, ale nikdy ho nevystavuj bez autentizace. Ukazuje kompletní topologii tvých služeb.

Bezpečnostní poznámka k Docker socketu

Přístup k /var/run/docker.sock znamená v praxi root na hostiteli. Kdokoliv, kdo prolomí Traefik, ovládne stroj. Připojení :ro na tom nic nemění, protože socket je API, ne soubor.

Kdo to bere vážně, dá mezi Traefik a socket proxy (tecnativa/docker-socket-proxy), která propustí jen čtení kontejnerů.

Pro homelab je to přijatelné riziko, ale stojí za to o něm vědět. Caddy tenhle problém nemá.

Diagnostika

docker compose logs -f traefik
docker inspect nazev-kontejneru | grep -A20 Labels
Problém Příčina
Kontejner Traefik nevidí chybí traefik.enable=true nebo není ve stejné síti
404 page not found pravidlo Host() nesedí, nebo chybí router
Bad Gateway špatný loadbalancer.server.port
Certifikát se nevydá acme.json nemá práva 600, nebo port 80 není dostupný

Ta práva na acme.json jsou klasika — Traefik odmítne soubor s volnějšími právy použít a v logu to napíše nenápadně.

Clone this wiki locally