Search code examples
dockerdocker-swarmtraefikdocker-swarm-mode

Docker Swarm + Traefik: Expose Traefik GUI through frontend rule; Service / Container port redirection


I am trying to use Traefik with Docker Swarm backend, and I am using the stack file below:

version: "3"

services:

  traefik:
    image: traefik:1.5
    command: --web --docker --docker.swarmmode --docker.watch --docker.domain=sample.com --logLevel=DEBUG 
    deploy:
      placement:
        constraints: [node.role==manager]
      restart_policy:
        condition: on-failure
      labels:
        - "traefik.port=8080"
        - "traefik.docker.network=sample-network"
        - "traefik.frontend.rule=Host:traefik.sample.com"
    ports:
      - "80:80"
      - "8080:8080"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /dev/null:/traefik.toml
    networks:
      - sample-network

  portainer:
    image: portainer/portainer:latest
    command: --no-auth -H unix:///var/run/docker.sock
    deploy:
      placement:
        constraints: [node.role == manager]
      labels:
        - "traefik.portainer.port=7777"
        - "traefik.docker.network=sample-network"
        - "traefik.frontend.rule=Host:portainer.sample.com"
    ports:
      - "7777:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - sample-network

networks:
  sample-network:

I have 2 questions that I am trying to wrap my head around:

1) (Exposing Traefik dashboard through frontend rule) I can access Traefik's web dashboard on sample.com:8080, yet I cannot access it through traefik.sample.com.

2) (Port Redirection on containers/services) I can access Portainer GUI through sample.com:7777, yet I cannot access it through portainer.sample.com. I am more curious of port redirection, because how will I setup 2 services in a single stack file if I encounter 2 images publishing to the same port? My service label declarations will clash at traefik.port=XXXX


Solution

  • You don´t need the traefik labels on the traefik service itself. It´s accessed from the outside over the specified ports:

      ports:
      - "80:80"
      - "8080:8080"
      - "443:443"
    

    On the portainer service you don´t need the port mappings because you probably want to route the request with traefik. Because traefik and portainer are in the same docker network traefik can access portainer on every port. Therefore the port for traefik have to match the real portainer port:

     labels:
        - "traefik.port=9000"
        - "traefik.docker.network=sample-network"
        - "traefik.frontend.rule=Host:portainer.sample.com"
    

    In the current setup you have to request traefik with Host:portainer.sample.com. You can test it with

    curl --verbose --header 'Host: portainer.sample.com' 'http://<DockerhostIp>:80'
    

    Edit: Updated curl

    Edit 2: Reaction to the edit of PO

    The portainer.sample.com DNS entry will have to point to your docker host. Then traefik will route it to the correct container.

    An alternative is to specifiy a traefik prefix:

     "traefik.frontend.rule=Host:site1.org;PathPrefixStrip: /sub/"
    

    With the rule all requests on site1.org/sub will routed to this specific service/container.

    Have a look at Traefik-Docker-Sample

    Edit 3:

    The self route for the dashboard/webui should work with:

      labels:
        - "traefik.port=8080"
        - "traefik.docker.network=sample-network"
        - "traefik.frontend.rule=Host:traefik.sample.com"
    

    Just be sure that you have a DNS entry for traefik.sample.com. To check if the traefik setup works you can also run

     curl --verbose -H Host:traefik.sample.com <DockerHostIp>