version: '3.8' networks: traefik-public: external: true volumes: traefik_letsencrypt: external: true tsdproxydata: external: true configs: traefik_dynamic: external: true tsdproxy-config: external: true name: tsdproxy.yaml secrets: cf_api_token: external: true tsdproxy_authkey: external: true services: traefik: image: traefik:latest ports: - "80:80" - "443:443" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - traefik_letsencrypt:/letsencrypt networks: - traefik-public secrets: - cf_api_token environment: # Cloudflare API Token (with DNS edit permissions for your domain) - CF_DNS_API_TOKEN_FILE=/run/secrets/cf_api_token - CF_ZONE_API_TOKEN_FILE=/run/secrets/cf_api_token # Optional: your Pi-hole DNS can stay dns: - 192.168.1.196 - 192.168.1.245 - 1.1.1.1 command: # Entrypoints - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" # SWARM Provider - "--providers.swarm=true" - "--providers.swarm.network=traefik-public" - "--providers.swarm.exposedbydefault=false" # File Provider (Dynamic Config) - "--providers.file.filename=/dynamic.yml" - "--providers.file.watch=true" # Dashboard - "--api.dashboard=true" - "--api.insecure=false" # HTTP -> HTTPS - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" # Let's Encrypt / ACME Cloudflare DNS Challenge - "--certificatesresolvers.cfresolver.acme.email=sterlenjohnson6@gmail.com" - "--certificatesresolvers.cfresolver.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.cfresolver.acme.dnschallenge=true" - "--certificatesresolvers.cfresolver.acme.dnschallenge.provider=cloudflare" # Optional: increase delay for propagation - "--certificatesresolvers.cfresolver.acme.dnschallenge.propagation.delayBeforeChecks=60" # Logging - "--log.level=INFO" deploy: placement: constraints: - node.role == manager labels: # Dashboard Router - "traefik.enable=true" - "traefik.http.routers.traefik.rule=Host(`traefik.sterl.xyz`)" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.tls.certresolver=cfresolver" - "traefik.http.services.traefik.loadbalancer.server.port=8080" - "traefik.http.routers.traefik.service=api@internal" whoami: image: traefik/whoami networks: - traefik-public deploy: labels: # Whoami Router - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`whoami.sterl.xyz`)" - "traefik.http.routers.whoami.entrypoints=websecure" - "traefik.http.routers.whoami.tls.certresolver=cfresolver" - "traefik.http.services.whoami.loadbalancer.server.port=80" tsdproxy: image: almeidapaulopt/tsdproxy:1.1.0 networks: - traefik-public configs: - source: tsdproxy-config target: /config/tsdproxy.yaml uid: "0" gid: "0" mode: 0444 secrets: - tsdproxy_authkey volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - tsdproxydata:/data environment: - TSDPROXY_AUTHKEYFILE=/run/secrets/tsdproxy_authkey - DOCKER_HOST=unix:///var/run/docker.sock healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 20s deploy: placement: constraints: - node.labels.leader == true resources: limits: memory: 512M reservations: memory: 256M labels: - "traefik.enable=true" - "traefik.http.routers.tsdproxy.rule=Host(`tsdproxy.sterl.xyz`)" - "traefik.http.routers.tsdproxy.entrypoints=websecure" - "traefik.http.routers.tsdproxy.tls.certresolver=cfresolver" - "traefik.http.services.tsdproxy.loadbalancer.server.port=8080" - "traefik.swarm.network=traefik-public" - "tsdproxy.enable=true" - "tsdproxy.name=tsdproxy"