Traefik accessible via IP but not domain when in Swarm Mode

Hey,

previously I set up a single Docker host with Traefik and connected domains to it. That works fine. Now I'm trying out Docker Swarm, but having trouble with accessing Traefik via domain.

I can access the dashboard via the IPv4 address, but when I switch the Host rule to my domain I'm getting an endless loading screen. However, the DNS record gets correctly resolved to the server's IPv4. I'm not exactly sure if that's an issue with my Traefik setup or my Docker Swarm setup.

My Docker Swarm setup:
I've got three manager nodes, each connected to the internet via the "eth0" network interface and a private network via the "ens10" interface. The private network I want to use for the Docker Swarm traffic.

Public (eth0) IPv4 of the first manager node: 12.34.56.78
ens10 IPv4 of that node: 10.0.1.1

My domain is connected to that public IPv4 via an A record and gets correctly resolved.

For that I've created the Docker Swarm via:

# On the first manager node
docker swarm init --advertise-addr ens10 --listen-addr ens10

# On the other two manager nodes
docker swarm join --advertise-addr ens10 --listen-addr ens10 --token mytoken 10.0.1.1:2377

The network gets successfully created and all nodes are able to join.

Next, deploy a stack with Traefik:

version: "3.8"

services:
  traefik:
    image: traefik:v2.3.2

    networks:
      - traefik_overlay

    deploy:
      replicas: 1
      placement:
        constraints:
          - "node.hostname==swarm1-node1" # Only deploy to the first manager node

      labels:
        traefik.enable: "true"

        traefik.http.routers.dashboard_http.rule: Host(`12.34.56.78`) # Works with my public IPv4 address but not my domain
        traefik.http.routers.dashboard_http.entrypoints: web
        traefik.http.routers.dashboard_http.service: api@internal
        traefik.http.services.apiInternalDummy.loadbalancer.server.port: 8080 # Required by Traefik when in Swarm mode

    ports:
      - published: 80 # HTTP
        target: 80

    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
        read_only: true

      - type: bind
        source: /home/ansible/traefik/traefik.toml
        target: /etc/traefik/traefik.toml
        read_only: true

      - /home/ansible/traefik/acme.json:/acme.json

networks:
  traefik_overlay:
    driver: overlay
    name: traefik_overlay

This stack/service gets successfully deployed to the first manager node (swarm1-node1/10.0.1.1).

My toml for Traefik:

[providers.docker]
  exposedByDefault = false
  swarmMode = true
  network = "traefik_overlay"

[entryPoints]
  [entryPoints.web]
    address = ":80"

[api]
  dashboard = true

Judging by the logs of the Traefik container, all labels and the toml get successfully read by Traefik., even when I switch the Host url to my domain. Therefore I'm not sure if that's some issue with Docker Swarm itself or Traefik.

Thanks for any help. I'm trying to get this to work for many hours now :sob:

Update:
It seems to be working when I publish the port via host mode. Is that required? I've been under the impression that the Docker Swarm Load Balancer should route the traffic to the correct node with Traefik on it.

Found the culprit:
I just found out that Docker Swarm apparently doesn't really work with IPv6 yet. Since my domain also had an AAAA record set, it explains why I could reach my server via IPv4 without any issues but got endless loading screen when accessing via my domain. My PC propably tried to connect via IPv6 then. I've removed the AAAA record and now everything works fine.

2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.