Traefik kao reverse proxy na VPS-u

Zašto reverse proxy, Traefik s Docker labelima, Let's Encrypt, entrypointi, middleware i TLS. Plus rizici Docker socketa i kada su Nginx ili Caddy jednostavniji.

Docker Networking Traefik
Traefik kao reverse proxy na VPS-u

Reverse proxy sjedi ispred aplikacija: prima HTTP/HTTPS s interneta, terminira TLS, rutira prema internim servisima i po potrebi dodaje headere, rate limit ili auth. Na VPS-u s više kontejnera to znači jedan ulaz na 80/443 umjesto publishanja svake aplikacije na javni port.

Traefik se dobro uklapa uz Docker Compose jer konfiguraciju rute može čitati iz labela na servisima. Stack discipline pokriva Docker Compose u produkciji. Certifikate i proxy config tretirajte kao dio backupa. Vidi backup strategiju 3-2-1.

Zašto reverse proxy

Jedan TLS terminacijski sloj (Let's Encrypt). Imena hostova (app.example.com) umjesto :8000 ili :3000. Interne aplikacije ostaju na Docker mreži bez javnog porta. Mjesto za zajednički middleware (HSTS, compress, IP allowlist za admin).

Traefik + Docker labels

services:
  traefik:
    image: traefik:v3.3
    restart: unless-stopped
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.le.acme.httpchallenge=true
      - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
      - [email protected]
      - --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
      - --api.dashboard=false
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt
    networks:
      - proxy

  web:
    image: ghcr.io/example/app:1.4.2
    restart: unless-stopped
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.http.routers.app.rule=Host(`app.example.com`)
      - traefik.http.routers.app.entrypoints=websecure
      - traefik.http.routers.app.tls.certresolver=le
      - traefik.http.services.app.loadbalancer.server.port=8000

volumes:
  letsencrypt:

networks:
  proxy:

exposedbydefault=false je bitan: bez njega svaki kontejner s portom može slučajno postati routable. Pinajte Traefik minor verziju, ne samo latest.

Let's Encrypt HTTP challenge

HTTP-01 challenge traži da Let's Encrypt dođe na :80 do Traefika. DNS A/AAAA zapis mora pokazivati na VPS prije prvog izdavanja certifikata. Alternativa DNS-01 (API token kod DNS providera) treba kad challenge ide za wildcard (*.example.com) ili kad 80 nije dostupan.

Datoteka acme.json mora biti mode 600. Backupirajte volume. Gubitak znači reissue (rate limit Let's Encrypta postoji; ne spamajte).

Entrypointi i redirect na HTTPS

command:
  - --entrypoints.web.address=:80
  - --entrypoints.web.http.redirections.entrypoint.to=websecure
  - --entrypoints.web.http.redirections.entrypoint.scheme=https
  - --entrypoints.websecure.address=:443

HTTP entrypoint ostaje zbog ACME HTTP-01 i redirecta; aplikacijski routeri tipično sjede na websecure.

Middleware osnove

labels:
  - traefik.http.middlewares.app-headers.headers.stsSeconds=31536000
  - traefik.http.middlewares.app-headers.headers.stsIncludeSubdomains=true
  - traefik.http.middlewares.app-headers.headers.contentTypeNosniff=true
  - traefik.http.middlewares.admin-allow.ipallowlist.sourcerange=203.0.113.10/32
  - traefik.http.routers.app.middlewares=app-headers@docker
  - traefik.http.routers.admin.middlewares=admin-allow@docker,app-headers@docker

IP allowlist za admin koristan je, ali nije zamjena za autentikaciju. Rate limit i basicAuth middleware postoje. Koristite ih namjerno, ne kao jedini sloj zaštite aplikacije.

TLS

Uz certresolver Traefik dogovara certifikat po router host pravilu. Provjerite lanac u browseru i curl -vI https://app.example.com. HSTS uključite tek kad ste sigurni da HTTPS radi na svim relevantnim hostovima. Inače browser zalijepi HTTPS i otežava hitni rollback.

Docker socket: rizik (pažljivo)

Mount /var/run/docker.sock u Traefik kontejner daje procesu moćan API pristup Docker daemonu (u praksi blizu root na hostu). Za mali VPS to je čest kompromis, ali shvatite blast radius: kompromitirani Traefik/proxy kontejner ≈ kompromitirani host.

Mountajte socket :ro (smanjuje neke write puteve, ali Docker API i dalje može biti opasan). Razmotrite Docker Socket Proxy (npr. Tecnativa) koji whitelist-a samo potrebne API endpointove za Traefik. Ne izlažite Traefik dashboard javno. Ako treba, samo uz jake kontrole (VPN + auth). Držite Traefik image ažurnim; pratite CVE-ove.

Kada su Nginx ili Caddy jednostavniji

Caddy daje automatski HTTPS s minimalnom konfiguracijom. Dobar je za par statičnih / reverse_proxy blokova bez Dockera label orchestracije. Nginx je predvidljiv, ima ogromnu bazu znanja i fine tuning (cache, complex rewrite). Konfig je eksplicitna datoteka; nema automatske detekcije kontejnera osim ako dodate template/generator. Traefik je sjajan kad često dodajete/mičete kontejnere i želite labele umjesto ručnog reloadanja proxy confa.

Ako imate jednu Django aplikaciju i rijetko mijenjate topologiju, Caddy ili Nginx često manje pomičnih dijelova. Ako ste već all-in na Compose labele, Traefik je prirodan.

Česte greške

exposedbydefault=true (default u nekim starim tutorialima) i slučajno izloženi interni servisi. Dashboard na :8080 publishan na internet. Krivi internal port u loadbalancer.server.port. DNS još ne pokazuje na VPS dok Traefik spam-a ACME. Zaboravljen redirect HTTP→HTTPS ili HSTS prerano. Socket mount bez svijesti o riziku.

Mreža i izolacija servisa

Stavite Traefik i javne aplikacije na zajedničku proxy mrežu. Bazu i Redis držite na internoj mreži bez Traefik labela i bez publishanih portova. Aplikacija dosegne DB preko service namea; internet dosegne samo ono što ima traefik.enable=true.

services:
  db:
    networks: [internal]
  web:
    networks: [internal, proxy]
  traefik:
    networks: [proxy]

To smanjuje štetu ako netko krivo postavi label ili ako exposedbydefault ostane uključen u starom compose snippetu.

Observability proxyja

Kad routing ne radi, prvo provjerite Traefik logove i Docker labele (docker inspect na servisu). Access log uključite privremeno pri debugiranju; u produkciji razmislite o razini logiranja da ne pišete nepotrebne PII u disk.

Metrike (Prometheus endpoint) korisne su kad imate više routera. Ne morate ih uvoditi prvog dana, ali rezervirajte interno-only ekspoziciju ako ih uključite.

Zaključak

Traefik uz Compose labele radi dobro, ali socket i exposedbydefault traže disciplinu. Za manje pomičnih dijelova razmotrite Caddy ili Nginx. Pomoć oko proxyja i Compose stacka: DevOps usluge.