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