Reverse Proxy Traefik - sparkycz1/honeypot-shelf GitHub Wiki
🔒 Reverse proxy: Traefik
Already run Traefik? Point a router at it and move on.
Use this if you already run Traefik on the host where Honeypot Shelf's
docker compose up -d --build (the base file, without
docker-compose.caddy.yml) is running, exposing the app on
127.0.0.1:8080 (or whatever APP_PORT you set). Once working, consider
also setting APP_BIND_ADDRESS=127.0.0.1 (no docker-compose.yml edit
needed) so the app is only reachable through this proxy.
Two ways to wire Traefik up to a service: a static file provider entry pointing at an address, or Docker labels via Traefik's own Docker provider. The file provider is simpler when Honeypot Shelf and Traefik aren't in the same Compose project (the default here).
⚙️ Static config (traefik.yml)
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
http3: {}
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
providers:
file:
directory: /etc/traefik/dynamic
watch: true
http3: {} enables HTTP/3 on the websecure entrypoint (Traefik still
needs 443/udp published/open for QUIC to actually work).
🔐 TLS options: restrict to TLS 1.3 only (dynamic/tls.yml)
tls:
options:
tls13only:
minVersion: VersionTLS13
maxVersion: VersionTLS13
🔀 Route to Honeypot Shelf (dynamic/Honeypot Shelf.yml)
http:
routers:
Honeypot Shelf:
rule: "Host(`your-domain.example.com`)"
entryPoints:
- websecure
service: Honeypot Shelf
tls:
certResolver: letsencrypt
options: tls13only@file
middlewares:
- Honeypot Shelf-headers
middlewares:
Honeypot Shelf-headers:
headers:
stsSeconds: 63072000
stsIncludeSubdomains: true
contentTypeNosniff: true
referrerPolicy: "no-referrer"
customResponseHeaders:
Server: ""
services:
Honeypot Shelf:
loadBalancer:
servers:
- url: "http://127.0.0.1:8080"
If Traefik runs inside Docker, 127.0.0.1 from its point of view is the
Traefik container, not the host — either run Traefik with
network_mode: host, or use the host's Docker-bridge gateway address
(commonly 172.17.0.1, check ip addr show docker0) in the service URL
above.
🏷️ Alternative: Docker label-based discovery
If you'd rather use Traefik's Docker provider (labels on the web
container) instead of the file provider above, web and Traefik need to
share a Docker network — add an external network to both
docker-compose.yml (on the web service) and Traefik's compose file,
then label web:
labels:
- traefik.enable=true
- traefik.http.routers.Honeypot Shelf.rule=Host(`your-domain.example.com`)
- traefik.http.routers.Honeypot Shelf.entrypoints=websecure
- traefik.http.routers.Honeypot Shelf.tls.certresolver=letsencrypt
- traefik.http.routers.Honeypot Shelf.tls.options=tls13only@file
- traefik.http.services.Honeypot Shelf.loadbalancer.server.port=8080
This requires exposing the Docker socket to the Traefik container — a meaningfully larger trust boundary than the file-provider approach above — only do this if you already accept that trade-off for your other services.
🔎 Verifying
curl -sIv https://your-domain.example.com/healthz 2>&1 | grep -Ei 'HTTP/|strict-transport|server:'
curl --http3 -sI https://your-domain.example.com/healthz # confirms HTTP/3
openssl s_client -connect your-domain.example.com:443 -tls1_2 </dev/null # should fail