I am trying to include Portainer in a docker-compose swarm, consisting of WordPress + MySQL and Traefik (reverse proxy). I am using the following definition:
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"
- "--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]
portainer:
image: portainer/portainer:latest
command: -H unix:///var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./portainer:/data
networks:
- traefik
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role==manager]
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=web"
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:
Everything works except portainer. When I visit localhost:9000 I just get a refused connection. The following non-swarm-mode docker-compose works, however:
version: '3'
services:
traefik:
image: "traefik:v2.0.0-rc3"
container_name: "traefik"
restart: always
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
portainer:
image: portainer/portainer
command: -H unix:///var/run/docker.sock
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./portainer:/data
ports:
- "9000:9000"
- "8000:8000"
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=web"
db:
image: mysql:5.7
restart: always
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
restart: always
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:
What am I doing wrong? The logs in each case are the same. In non-swarm-mode I can log in to the Portainer UI and see all my containers running, etc. But the swarm version simply refuses to connect, even when I pass Host rule (portainer.example.org). I have only been using Traefik for a few days, and am very likely to be making a simple configuration error (hopefully!).
Port Detection
Docker Swarm does not provide any port detection information to Traefik.
Therefore you must specify the port to use for communication by using the label traefik.http.services.<service_name>.loadbalancer.server.port (Check the reference for this label in the routing section for Docker).