services: traefik: image: traefik:v3.4 networks: # Connect to the 'traefik_proxy' overlay network for inter-container communication across nodes - traefik_proxy ports: # Expose Traefik's entry points to the Swarm # Swarm requires the long syntax for ports. - target: 80 # Container port (Traefik web entry point) published: 80 # Host port exposed on the nodes protocol: tcp # 'host' mode binds directly to the node's IP where the task runs. # 'ingress' mode uses Swarm's Routing Mesh (load balances across nodes). # Choose based on your load balancing strategy. 'host' is often simpler if using an external LB. mode: host - target: 443 # Container port ( Traefik websecure entry point) published: 443 # Host port protocol: tcp mode: host - target: 8080 # Container port (Traefik web entry point) published: 8080 # Host port exposed on the nodes protocol: tcp mode: host volumes: # Mount the Docker socket for the Swarm provider # This MUST be run from a manager node to access the Swarm API via the socket. - /var/run/docker.sock:/var/run/docker.sock:ro # Swarm API socket # - ./certs:/certs:ro # - ./dynamic:/dynamic:ro # Traefik Static configuration via command-line arguments command: # HTTP EntryPoint - "--entrypoints.web.address=:80" # HTTPS EntryPoint - "--entrypoints.websecure.address=:443" - "--entrypoints.websecure.http.tls=true" # Providers # Enable the Docker Swarm provider (instead of Docker provider) - "--providers.swarm.endpoint=unix:///var/run/docker.sock" # Watch for Swarm service changes (requires socket access) - "--providers.swarm.watch=true" # Recommended: Don't expose services by default; require explicit labels - "--providers.swarm.exposedbydefault=false" # Specify the default network for Traefik to connect to services - "--providers.swarm.network=myappstack_traefik_proxy" # API & Dashboard - "--api.dashboard=true" # Enable the dashboard - "--api.insecure=true" # Explicitly disable insecure API mod # Observability - "--log.level=INFO" # Set the Log Level e.g INFO, DEBUG - "--accesslog=true" # Enable Access Logs - "--metrics.prometheus=true" # Enable Prometheus deploy: mode: replicated replicas: 1 placement: # Placement constraints restrict where Traefik tasks can run. # Running on manager nodes is common for accessing the Swarm API via the socket. constraints: - node.role == manager # Traefik Dynamic configuration via labels # In Swarm, labels on the service definition configure Traefik routing for that service. labels: - "traefik.enable=true" # Dashboard router - "traefik.http.routers.dashboard.rule=PathPrefix(`/d2`)" - "traefik.http.routers.dashboard.entrypoints=web" - "traefik.http.middlewares.dashboard-stripprefix.stripprefix.prefixes=/d2" - "traefik.http.routers.dashboard.middlewares=dashboard-stripprefix" - "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.routers.dashboard.tls=false" # Service hint - "traefik.http.services.traefik.loadbalancer.server.port=8080" # Deploy the Whoami application whoami: image: traefik/whoami ports: - "8081:80" networks: - traefik_proxy deploy: labels: # Enable Service discovery for Traefik - "traefik.enable=true" # Define the Whoami router rule - match root path - "traefik.http.routers.whoami.rule=PathPrefix(`/whoami`)" # Expose Whoami on the HTTP entrypoint - "traefik.http.routers.whoami.entrypoints=web" - "traefik.http.middlewares.whoami-stripprefix.stripprefix.prefixes=/whoami" - "traefik.http.routers.whoami.middlewares=whoami-stripprefix" # Expose the whoami port number to Traefik - "traefik.http.services.whoami.loadbalancer.server.port=80" mode: replicated replicas: 1 # Define the overlay network for Swarm networks: traefik_proxy: driver: overlay # attachable: true