Files
GB-Traefik/README.md

3.1 KiB
Raw Blame History

Traefik Edge Stack

Reverse proxy for everything on this host. The goal: keep Cloudflare in front, expose a private LAN entrypoint, and let Docker stacks self-register through labels without leaking secrets.

Architecture Snapshot

  • Static config (traefik.yml)

    • EntryPoints: web/websecure on 10.0.0.225, internal_web/internal_websecure on 192.168.50.4.
    • Trusted IP lists are managed by scripts/update_cloudflare_ips.py.
    • Docker provider is discovery-only; every container opts in with labels.
    • File provider loads everything in dynamic.d/.
  • Dynamic config (dynamic.d/)

    • middlewares/ retry, compression, CrowdSec (rendered from template).
    • transports/fast-upstreams.yml shared connection pool tuning.
    • routers/ internal-only routers (public ones stay in labels).
  • Host networking
    Traefik runs with network_mode: host so it can bind to both IPs simultaneously. Switching to bridge mode would require duplicating Traefik or adding another L4 hop, so host mode stays.

Secrets Workflow

  1. Copy .env.example.env and fill:
    • CLOUDFLARE_EMAIL, CLOUDFLARE_DNS_API_TOKEN
    • CROWDSEC_LAPI_KEY
  2. Render secret-aware dynamic files:
    ./scripts/render_dynamic.sh
    
    This uses templates/crowdsec.yml.tmpl and writes dynamic.d/middlewares/crowdsec.yml (ignored by git).

Runbook

# start / update Traefik
docker compose up -d traefik

# refresh Cloudflare IPs and restart safely
python scripts/update_cloudflare_ips.py

# tail logs
tail -f traefik.log
tail -f access.log

Rotate CrowdSec keys? Edit .env, rerun render_dynamic.sh, then docker compose up -d traefik.

Service Labels Cheat Sheet

labels:
  - traefik.enable=true
  - traefik.http.routers.myapp.rule=Host(`app.example.com`)
  - traefik.http.routers.myapp.entrypoints=websecure
  - traefik.http.routers.myapp.tls.certresolver=letsencrypt
  - traefik.http.routers.myapp.middlewares=crowdsec@file,retry-fast@file,compress-middleware@file
  - traefik.http.services.myapp.loadbalancer.serversTransport=fast-upstreams@file
  - traefik.http.services.myapp.loadbalancer.server.port=3000
  - traefik.docker.network=traefik_default

Most stacks use the same middleware chain: CrowdSec bouncer (plugin), retry, and compression. Internal-only services skip CrowdSec by pointing at the internal_* entrypoints.

Performance Notes

  • Access logs are buffered with headers trimmed to keep syscalls down.
  • Compression enforces a 1KB minimum and respects the clients preferred encoding.
  • Shared transport keeps 64 idle connections per backend with aggressive idle/response timeouts.
  • retry-fast retries once after 50ms, smoothing transient Puma/Node hiccups without hammering backends.

Things to Remember

  • Watchtower is still enabled for Traefik; pin the image tag when you need deterministic upgrades.
  • scripts/update_cloudflare_ips.py rewrites the static trusted IP block and restarts Traefik—run it via cron.
  • Dashboard auth is intentionally disabled because access only happens from the LAN entrypoint. If that changes, re-enable basicauth.