# 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: