3

I am struggling to get a Docker swarm stack set up using traefik. I decided to try traefik as an alternative to jwolder/nginx-proxy, as unfortunately the latter does not seem to support Docker swrarm mode. But I'm finding traefik to be a problem (probably my fault!).

I have a WordPress container (replicated) and a MySQL container, alongside the traefik container. All of the containers in the swarm are created and start, and docker logs <container_id> reveals no errors, but when I visit 'example.org' (not the real domain) I just see 404 page not found. So it must be a communication issue between traefik and the containers I wish to proxy. However I also don't see the traefik dashboard, so perhaps soemthing else is going on.

Here is my docker-compose file:

version: '3'

services:
  traefik:
    image: traefik:latest
    command: --api.insecure=true \
      --providers.docker=true \
      --providers.docker.exposedbydefault=false \
      --providers.docker.swarmmode=true \
      --providers.docker.watch=true \
      --logLevel=DEBUG
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - traefik
    deploy:
      mode: global
      placement:
        constraints:
          - node.role == manager

  db:
    image: mysql:5.7
    volumes:
      - ./db/initdb.d:/docker-entrypoint-initdb.d
    networks:
      - traefik
    environment:
      MYSQL_ROOT_PASSWORD: <root_password>
      MYSQL_DATABASE: <db_name>
      MYSQL_USER: <db_user>
      MYSQL_PASSWORD: <user_password>
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3

  app:
    image: my-repo/wordpress:latest
    depends_on:
      - db
    networks:
      - traefik
    environment:
      - VIRTUAL_PORT=80
      - VIRTUAL_HOST=example.org
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      labels:
        - "traefik.enable=true"
        - "traefik.frontend.rule=Host:example.org"

networks:
  traefik:

The orignal nginx-proxy setup works nicely, but, as I say, won't allow me to run a swarm. I have been experimenting with traefik for only a day, so it's probably a schoolboy error of some kind.

N.B: I am aliasing my actual .org domain to 127.0.0.1 in my /etc/hosts. Perhaps that's an issue? I can't imagine it would be, I've been running Docker containers with that setup for ages without a problem.

ChrisM
  • 2,128
  • 1
  • 23
  • 41

1 Answers1

2

OK, so I got it to work in non-swarm mode with the following docker-compose file:

version: '3'

services:
  traefik:
    image: "traefik:v2.0.0-rc3"
    container_name: "traefik"
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - traefik

  db:
    image: mysql:5.7
    volumes:
      - ./db/initdb.d:/docker-entrypoint-initdb.d
    networks:
      - traefik
    environment:
      MYSQL_ROOT_PASSWORD: <root_password>
      MYSQL_DATABASE: <db_name>
      MYSQL_USER: <db_user>
      MYSQL_PASSWORD: <user_password>

  app:
    image: my-repo/wordpress:latest
    depends_on:
      - db
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`example.org`)"
      - "traefik.http.routers.app.entrypoints=web"

networks:
  traefik:

And then I tried the following swarm configuration, which worked:

version: '3'

services:
  traefik:
    image: "traefik:v2.0.0-rc3"
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmmode=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - traefik
    deploy:
      mode: global
      placement:
        constraints: [node.role==manager]

  db:
    image: mysql:5.7
    volumes:
      - ./db/initdb.d:/docker-entrypoint-initdb.d
    networks:
      - traefik
    environment:
      MYSQL_ROOT_PASSWORD: <root_password>
      MYSQL_DATABASE: <db_name>
      MYSQL_USER: <db_user>
      MYSQL_PASSWORD: <user_password>
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3

  app:
    image: my-repo/wordpress:latest
    networks:
      - traefik
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.app.rule=Host(`example.org`)"
        - "traefik.http.routers.app.entrypoints=web"
        - "traefik.http.services.app.loadbalancer.server.port=80"

networks:
  traefik:

More specifically, I got it to work only after adding the command

- "--providers.docker.endpoint=unix:///var/run/docker.sock"

and the proxied container label

- "traefik.http.services.app.loadbalancer.server.port=80"

... so I'm not really sure what I did right. Would be grateful for any light that could be shed on that.

It's working now, though, at least.

UPDATE: The Traefik docs state that the label

traefik.http.services.<service_name>.loadbalancer.server.port

is mandatory for Docker swarm mode (look under Services on that page). So it seems as if I was just missing that.

ChrisM
  • 2,128
  • 1
  • 23
  • 41