Traefil -> docker swarm -> Redis

Hi,
Trying to get a configuration setup and I'm not sure what I'm doing wrong. I have a stand alone docker instance running on a public subnet. Two containers are running. Portainer and Traefik. I have TLS with Protainer and the Dashboard working perfectly. On my private subnet I have a docker swarm configuration running and it is connected to the Traefik proxy running on the controller machine. I spun up a basic service of a redis instance and added all the proper labels and it seems to be configured properly. The problem is that the IP that keeps being used is part of the swarm's overlay network and any traffic pointed at the endpoint just times out. Is this configuration viable? I've seen some indications that Traefik won't work unless it is running on the swarm itself.
Thanks for your time.

Do you use TLS? Do you use a TCP router?

Hi bluepuma77,
Thanks for the question. I have turned TLS on and off in different combinations. Yes...using the TCP router.

Static config

  swarm:
    endpoint: "tcp://10.0.2.99:2375"

The response from the swarm

"tcp":{"routers":{"redis":{"entryPoints":["redis"],"rule":"HostSNI(`*`)","service":"redis"}},"services":{"redis":{"loadBalancer":{"servers":[{"address":"10.11.0.1:6379"}]}}}}

Tags on the stack in Deploy. Tried a few combinations

        - traefik.tcp.routers.redis.rule=HostSNI(`*`)
        #- traefik.tcp.routers.redis.tls=true
        #- traefik.docker.network=host
        - traefik.docker.lbswarm=true
        - traefik.tcp.services.redis.loadbalancer.server.port=6379
        - traefik.tcp.routers.redis.entrypoints=redis
        - traefik.enable=true
        - traefik.tcp.routers.redis.service=redis
redis-cli  -h <domain> -p 6379
<domain>:6379> ping
Error: Server closed the connection
2023-11-20T16:35:50Z DBG github.com/traefik/traefik/v3/pkg/tcp/proxy.go:41 > Handling TCP connection address=10.11.0.1:6379 remoteAddr=<myip>:47750

2023-11-20T16:36:20Z ERR github.com/traefik/traefik/v3/pkg/tcp/proxy.go:48 > Error while dialing backend error="dial tcp 10.11.0.1:6379: i/o timeout"

If I hit any of the nodes from the controller machine...works perfectly

Share your full Traefik static and dynamic configuration, and docker-compose.yml if used. Also from the target service.

################################################################
#
# Configuration sample for Traefik v2.
# https://github.com/traefik/traefik/blob/v2.10/traefik.sample.yml
#
# For Traefik v1: https://github.com/traefik/traefik/blob/v2.10/traefik.sample.toml
#
################################################################

################################################################
# Global configuration
################################################################
global:
  checkNewVersion: true
  sendAnonymousUsage: true

################################################################
# EntryPoints configuration
################################################################
entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: :443
  redis:
    address: :6379

################################################################
# Traefik logs configuration
################################################################
log:
  level: DEBUG
#  filePath: log/traefik.log
#  format: json

################################################################
# Access logs configuration
################################################################
accessLog:
  filePath: /etc/traefik/logs/access.log
  format: json
  fields:
    defaultMode: keep
    names:
      ClientAddr: keep
      ClientUsername: keep
      DownstreamStatus: keep
      OriginStatus: keep
      RequestAddr: keep
      RequestHost: keep
      RequestMethod: keep
      RequestPath: keep
      RequestPort: keep
      RequestProtocol: keep
      RouterName: keep
      ServiceAddr: keep
      ServiceName: keep
      StartLocal: keep
      entryPointName: keep
    headers:
      defaultMode: keep
################################################################
# API and dashboard configuration
################################################################
api:
  insecure: false
  dashboard: true
  #debug: true

################################################################
# Ping configuration
################################################################
ping:
  entryPoint: traefik

################################################################
# Provider  configuration backend
################################################################
providers:
  # Enable Docker configuration backend
  docker:
    exposedByDefault: true
  file:
    filename: /etc/traefik/dynamic.yml
    watch: true
  swarm:
    endpoint: "tcp://10.0.2.99:2375"
    # docker swarm mode (1.12+)
         
# Let's Encrypt Config
# certificatesResolvers:
#   letsEncrypt:
#     acme:
#       email: <REDACTED>
#       storage: /etc/traefik/acme.json
#       tlsChallenge: {}
#   staging:
#     acme:
#       email: <REDACTED>
#       storage: /etc/traefik/staging.json
#       caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
#       tlsChallenge: {}
http:
  middlewares:
    dashboard-auth:
      basicAuth:
        users:
          - "admin:...."
  routers:
    api:
      rule: Host(`dashboard.app.domain`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
      middlewares:
       - dashboard-auth
      service: api@internal
      tls: {}
tls:
  stores:
    default:
      defaultCertificate:
        certFile: /etc/traefik/certs/fullchain.pem
        keyFile: /etc/traefik/certs/privkey.pem
version: '3.7'

services:
  redis:
    image: redis:latest
    hostname: "redis.unc"
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - redisnet
    ports:
      - "6379:6379"
    deploy:
      endpoint_mode: vip
      labels:
        - traefik.tcp.routers.redis.rule=HostSNI(`*`)
        #- traefik.tcp.routers.redis.tls=true
        #- traefik.docker.network=host
        - traefik.docker.lbswarm=true
        - traefik.tcp.services.redis.loadbalancer.server.port=6379
        - traefik.tcp.routers.redis.entrypoints=redis
        - traefik.enable=true
        - traefik.tcp.routers.redis.service=redis
        
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
    environment:
      REDIS_REPLICATION_MODE: master

networks:
  redisnet:
    driver: overlay

volumes:
  redis_data:
    driver: local

Traefik compose is missing.

Note that you attach Redis to a Docker network that by default is not shared, so Traefik should not be able to connect to it.

I ran Traefik without compose.

Docker Swarm uses a mesh network for routing with overlays. If the request hits any node on the appropriate port it will route to the correct node using the IPVS service. That si my main issue, is that Traefik should be using a node IP address and the ingress overlay will take care of the rest, but instead it is behaving as if it was part of the swarm. Which goes to my initial question. Can Traefik work with providers that it is not apart of?

By default, Traefik gets the IPs of all instances of a Docker service and uses round-robin to forward requests to those Docker network IPs.

If you want Traefik to use the Docker service VIP instead, just set the option traefik.docker.lbswarm=true (doc).

If you want to use external Docker IPs, then use providers.docker.useBindPortIP=true (doc).