Add reference Traefik stack config for replication
ci/woodpecker/push/woodpecker Pipeline was successful Details

Stripped-down, generic version of the Traefik Swarm setup that the
tunnel-server depends on for dynamic label-based routing. Sanitized
of infrastructure-specific details so others can replicate the setup.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leopere 2026-02-09 16:06:29 -05:00
parent fd31e40285
commit 58092e24c8
Signed by: colin
SSH Key Fingerprint: SHA256:nRPCQTeMFLdGytxRQmPVK9VXY3/ePKQ5lGRyJhT5DY8
1 changed files with 84 additions and 0 deletions

84
traefik-reference.yml Normal file
View File

@ -0,0 +1,84 @@
# Reference Traefik stack configuration for Docker Swarm.
# This is NOT deployed by this project — it documents the Traefik setup
# that the tunnel-server depends on for dynamic routing via Swarm labels.
#
# Key requirements:
# - Docker Swarm provider enabled (--providers.docker.swarmMode=true)
# - Exposed by default OFF (--providers.docker.exposedbydefault=false)
# - A shared overlay network (e.g. "traefik")
# - An ACME cert resolver for automatic TLS
# - NO file providers — all routing is done via Docker service labels
#
# Deploy: docker stack deploy -c traefik-reference.yml traefik
networks:
traefik:
external: true
services:
traefik-http:
image: traefik:v2
command:
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik
- --serverstransport.insecureskipverify=true
- --log.level=ERROR
- --global.checknewversion=false
- --global.sendanonymoususage=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entryPoint.permanent=true
- --entryPoints.websecure.forwardedHeaders.insecure=true
- --entryPoints.websecure.transport.respondingTimeouts.idleTimeout=600s
- --entryPoints.websecure.transport.respondingTimeouts.readTimeout=600s
- --entryPoints.websecure.transport.respondingTimeouts.writeTimeout=600s
- --certificatesresolvers.letsencryptresolver.acme.httpchallenge=true
- --certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.letsencryptresolver.acme.email=admin@example.com
- --certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json
- --api.dashboard=true
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 443
published: 443
protocol: udp
mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-letsencrypt:/letsencrypt
networks:
- traefik
deploy:
endpoint_mode: dnsrr
replicas: 1
placement:
constraints:
- node.role == manager
labels:
traefik.enable: "true"
traefik.docker.network: "traefik"
traefik.http.routers.traefik-dashboard.rule: "Host(`traefik.example.com`)"
traefik.http.routers.traefik-dashboard.entrypoints: "websecure"
traefik.http.routers.traefik-dashboard.tls: "true"
traefik.http.routers.traefik-dashboard.tls.certresolver: "letsencryptresolver"
traefik.http.routers.traefik-dashboard.service: "api@internal"
traefik.http.services.traefik-dashboard.loadbalancer.server.port: "888"
update_config:
order: stop-first
failure_action: rollback
restart_policy:
condition: on-failure
volumes:
traefik-letsencrypt: