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.
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.
Related
I am trying to deploy Wordpress application on docker swarm stack, behind Traefik reverse proxy, I wanted to use Nginx for reverse proxying but as the the Wordpress is deployed with 2 replicas I am facing session time out issue, therefore I am trying the use Traefik instaed to configure sticky session later.
I have deployed the Traefik service successfully and can access the dashboard, but the Wordpress is not being proxied and it is not showing in the services list on the dashboard.
Traefik Dashboard Screenshot
Traefik Dashboard 2
Traefik Proxy yaml File:
version: '3.3'
services:
traefik:
image: traefik:v2.2
ports:
- 80:80
- 443:443
deploy:
placement:
constraints:
# Make the traefik service run only on the node with this label
# as the node with it has the volume for the certificates
- node.labels.traefik-public.traefik-public-certificates == true
labels:
- traefik.enable=true
- traefik.docker.network=traefik-public
- traefik.constraint-label=traefik-public
- traefik.http.middlewares.admin-auth.basicauth.users=${USERNAME?Variable not set}:${HASHED_PASSWORD?Variable not set}
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
- traefik.http.routers.traefik-public-http.rule=Host(`${DOMAIN?Variable not set}`)
- traefik.http.routers.traefik-public-http.entrypoints=http
- traefik.http.routers.traefik-public-http.middlewares=https-redirect
- traefik.http.routers.traefik-public-https.rule=Host(`${DOMAIN?Variable not set}`)
- traefik.http.routers.traefik-public-https.entrypoints=https
- traefik.http.routers.traefik-public-https.tls=true
- traefik.http.routers.traefik-public-https.service=api#internal
- traefik.http.routers.traefik-public-https.tls.certresolver=le
- traefik.http.routers.traefik-public-https.middlewares=admin-auth
- traefik.http.services.traefik-public.loadbalancer.server.port=8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-public-certificates:/certificates
command:
- --providers.docker
- --providers.docker.constraints=Label(`traefik.constraint-label`, `traefik-public`)
- --providers.docker.exposedbydefault=false
- --providers.docker.swarmmode
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
- --certificatesresolvers.le.acme.email=${EMAIL?Variable not set}
- --certificatesresolvers.le.acme.storage=/certificates/acme.json
- --certificatesresolvers.le.acme.tlschallenge=true
- --accesslog
- --log
- --api
networks:
- traefik-public
volumes:
traefik-public-certificates:
networks:
traefik-public:
external: true
Wordpress yaml File:
version: "3.4"
services:
db:
image: mariadb
secrets:
- db_user
- db_pass
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_pass
MYSQL_USER_FILE: /run/secrets/db_user
MYSQL_PASSWORD_FILE: /run/secrets/db_pass
MYSQL_DATABASE_NAME: wpdb
ports:
- 3306:3306
networks:
- backend
volumes:
- db-data:/var/lib/mysql
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 60s
wp:
image: wordpress
secrets:
- db_user
- db_pass
depends_on:
- db
labels:
- traefik.enable=true
- traefik.constraint-label=traefik-public
- traefik.docker.network=traefik-public
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
- traefik.http.routers.wp.rule=Host(`example.com`)
- traefik.http.routers.wp.entrypoints=http
- traefik.http.routers.wp.middlewares=https-redirect
- traefik.http.routers.wp-secured.rule=Host(`example.com`)
- traefik.http.routers.wp-secured.entrypoints=https
- traefik.http.routers.wp-secured.tls=true
- traefik.http.routers.wp-secured.tls.certresolver=le
- traefik.http.services.wp.loadbalancer.server.port=8080
environment:
WORDPRESS_DB_HOST: 192.168.20.30:3306 # node IP
WORDPRESS_DB_USER_FILE: /run/secrets/db_user
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_pass
WORDPRESS_DB_NAME: wpdb
networks:
- backend
- traefik-public
volumes:
- wp-data:/var/www/html
deploy:
replicas: 2
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 60s
networks:
backend:
external: false
traefik-public:
external: true
volumes:
wp-data:
db-data:
secrets:
db_user:
file: ./db_user.txt
db_pass:
file: ./db_pass.txt
```
I'm having a problem persisting data with docker-compose.
I want my service chatmysql to persist data I put inside a database, but everytime i run docker-compose down it all vanishes.
I checked directory /var/lib/docker/volumes to see if it stores data there when containers are running and the volume was completely empty.
I didn't have that issue when I was running containers with docker run command so I guess its fault of my docker-compose.yaml file. Can someone help me?
I'm running this on Ubuntu 20.04.
version: '3'
services:
chatmysql:
image: mysql/mysql-server
container_name: chatmysql
hostname: db
user: root
networks:
- chatnet
ports:
- 3307:3306
volumes:
- chatmysqlvolume:/lib/var/mysql
chatbackend:
depends_on:
- chatmysql
build:
context: backend/src
container_name: chatbackend
hostname: backend
networks:
- chatnet
ports:
- 8080:8080
environment:
- MYSQLUSERNAME=${MYSQLUSERNAME:-user}
- MYSQLPASSWORD=${MYSQLPASSWORD:?database password not set}
- MYSQLHOST=${MYSQLHOST:-db}
- MYSQLPORT=${MYSQLPORT:-3306}
- MYSQLDBNAME=${MYSQLDBNAME:-test}
restart: always
deploy:
restart_policy:
condition: on-failure
chatfrontend:
build: frontend
container_name: chatfrontend
hostname: front
networks:
- chatnet
ports:
- 3000:3000
volumes:
chatmysqlvolume:
networks:
chatnet:
driver: bridge
You need to change the mounted volume, try this :
version: '3.7'
services:
chatmysql:
image: mysql/mysql-server
container_name: chatmysql
hostname: db
user: root
networks:
- chatnet
ports:
- 3307:3306
volumes:
- chatmysqlvolume:/var/lib/mysql
chatbackend:
depends_on:
- chatmysql
build:
context: backend/src
container_name: chatbackend
hostname: backend
networks:
- chatnet
ports:
- 8080:8080
environment:
- MYSQLUSERNAME=${MYSQLUSERNAME:-user}
- MYSQLPASSWORD=${MYSQLPASSWORD:?database password not set}
- MYSQLHOST=${MYSQLHOST:-db}
- MYSQLPORT=${MYSQLPORT:-3306}
- MYSQLDBNAME=${MYSQLDBNAME:-test}
restart: always
deploy:
restart_policy:
condition: on-failure
chatfrontend:
build: frontend
container_name: chatfrontend
hostname: front
networks:
- chatnet
ports:
- 3000:3000
volumes:
chatmysqlvolume:
networks:
chatnet:
driver: bridge
I am attempting to create multiple Docker-Compose projects and have them share a single service, a database server. I'm currently unable to get projects to use my mariadb instance. I'm not sure if my issues is in traefik or docker. I can get wordpress to recognize the database if it is included in the same docker-compose, but as I would ultimately like to not have multiple instances of a database server running, I would prefer it to be it's own project.
# ~/docker/traefik/docker-compose.yml
version: "3.3"
services:
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
- "--api=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.dnschallenge=true"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=namedotcom"
- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.myresolver.acme.email=<MY-EMAIL>"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
networks:
t2_proxy:
ports:
- "80:80"
- "443:443"
environment:
- "NAMECOM_USERNAME=<My-USERNAME>
- "NAMECOM_API_TOKEN=<My-Token>
labels:
# Dashboard
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`api.mydomain.com`)"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.middlewares=admin"
- "traefik.http.routers.traefik.tls.certresolver=myresolver"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.middlewares.admin.basicauth.users=myuser:mypasswordhash/"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# global redirect to https
- "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirs.entrypoints=web"
- "traefik.http.routers.redirs.middlewares=redirect-to-https"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
t2_proxy:
# ~/docker/db/docker-compose.yml
version: '3.3'
services:
mysql:
image: mariadb
container_name: "mariadb"
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: wordpressDB
MYSQL_USER: wordpressUSER
MYSQL_PASSWORD: wordpressPW
networks:
default:
ports:
- 3306:3306
adminer:
image: adminer
restart: always
container_name: "adminer"
labels:
- "traefik.enable=true"
- "traefik.http.routers.adminer.rule=PathPrefix(`/adminer`)"
- "traefik.http.routers.adminer.entrypoints=websecure"
- "traefik.http.routers.adminer.tls.certresolver=myresolver"
networks:
- default
- traefik_t2_proxy
networks:
default:
traefik_t2_proxy:
external: true
# ~/docker/wordpress/docker-compose.yml
version: '3.3'
services:
wordpress:
image: wordpress:latest
restart: always
container_name: "mySite"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpressUSER
WORDPRESS_DB_PASSWORD: wordpressPW
WORDPRESS_DB_NAME: wordpressDB
networks:
traefik_t2_proxy:
db_default:
labels:
- "traefik.enable=true"
- "traefik.http.routers.wp2.rule=PathPrefix(`/wordpress`)"
- "traefik.http.routers.wp2.entrypoints=websecure"
- "traefik.http.routers.wp2.tls.certresolver=myresolver"
volumes:
db_data: {}
networks:
traefik_t2_proxy:
external: true
db_default:
external: true
You can have multiple docker-compose files, with the same network and run them together as below:
docker-compose -f docker-compose-1.yml -f docker-compose-2.yml up -d
But if you need the services to recognize eachother, the networks should be the same. Give your traefik_t2_proxy network to mysql too.
I have docker-compose build with symfony on apache and angular on nginx. It is possible that more docker-compositions can be run, so now I want to make my own DNS using traefik - I want to set hostname of each app, make docker-compose up and resolve apps with hostname when they are ready.
Traefik docker-compose:
version: '3.1'
networks:
proxy:
external: true
internal:
external: false
services:
traefik:
image: traefik:v2.1
command: --api.insecure=true --providers.docker
labels:
- traefik.frontend.rule=Host:monitor.docker.localhost
- traefik.port=8080
networks:
- proxy
ports:
- 80:80
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Apps docker-compose:
# Run docker-compose build
# Run docker-compose up
# Live long and prosper
version: '3.1'
networks:
proxy:
external: true
internal:
external: false
services:
apache:
build: .docker/apache
container_name: sf4_apache
volumes:
- .docker/config/vhosts:/etc/apache2/sites-enabled
- ./backend:/home/wwwroot/sf4
depends_on:
- php
labels:
- traefik.http.routers.sf4_apache.rule=Host(`symfony.docker.localhost`)
- traefik.http.services.apache.loadbalancer.server.port=80
networks:
- internal
- proxy
php:
build: .docker/php
container_name: sf4_php
volumes:
- ./backend:/home/wwwroot/sf4
- ./executor:/home/wwwroot/pipe
networks:
- internal
labels:
- traefik.enable=false
nginx:
container_name: angular_nginx
build: .docker/nginx
volumes:
- ./frontend/dist/frontend:/usr/share/nginx/html
ports:
- "81:80"
- "443:443"
labels:
- traefik.http.routers.angular_nginx.rule=Host(`angular.docker.localhost`)
networks:
- internal
- proxy
node:
build: .docker/node
container_name: angular_node
ports:
- 4200:4200
volumes:
- ./frontend:/home/node/app/frontend
tty: true
command:
- /bin/sh
- -c
- |
cd /home/node/app/frontend && npm start
expose:
- "4200"
networks:
- internal
labels:
- traefik.enable=false
Can't make it work: sometimes I get Bad Gateway at domains (symfony.docker.localhost), sometimes it crushed because both servers using one port, so please help me to run this correctly
First, docker frontend and backend are deprecated in version 2.1 check this link
here is an example of doing the same in traefik 2.1
version: '3.7'
networks:
traefik:
external: true
volumes:
db_data:
services:
proxy:
image: traefik:v2.1
command:
- '--providers.docker=true'
- '--entryPoints.web.address=:80'
- '--providers.providersThrottleDuration=2s'
- '--providers.docker.watch=true'
- '--providers.docker.swarmMode=true'
- '--providers.docker.swarmModeRefreshSeconds=15s'
- '--providers.docker.exposedbydefault=false'
- '--providers.docker.defaultRule=Host("local.me")'
- '--accessLog.bufferingSize=0'
- '--api=true'
- '--api.dashboard=true'
- '--api.insecure=true'
- '--ping.entryPoint=web'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:ro'
ports:
- '80:80'
- '8080:8080'
deploy:
restart_policy:
condition: any
delay: 5s
max_attempts: 3
window: 120s
update_config:
delay: 10s
order: start-first
parallelism: 1
rollback_config:
parallelism: 0
order: stop-first
logging:
driver: json-file
options:
'max-size': '10m'
'max-file': '5'
networks:
- traefik
mysql:
image: mysql:5.7
command: mysqld --general-log=1 --general-log-file=/var/log/mysql/general-log.log
deploy:
restart_policy:
condition: any
delay: 5s
max_attempts: 3
window: 120s
update_config:
delay: 10s
order: start-first
parallelism: 1
rollback_config:
parallelism: 0
order: stop-first
logging:
driver: json-file
options:
'max-size': '10m'
'max-file': '5'
networks:
- traefik
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: dummy
MYSQL_DATABASE: rails_blog_production
rails_blog_web:
image: wshihadeh/rails_blog:demo-v1
command: 'web'
deploy:
labels:
- traefik.enable=true
- traefik.http.services.blog.loadbalancer.server.port=8080
- traefik.http.routers.blog.rule=Host(`blog.local.me`)
- traefik.http.routers.blog.service=blog
- traefik.http.routers.blog.entrypoints=web
- traefik.docker.network=traefik
restart_policy:
condition: any
delay: 5s
max_attempts: 3
window: 120s
update_config:
delay: 10s
order: start-first
parallelism: 1
rollback_config:
parallelism: 0
order: stop-first
logging:
driver: json-file
options:
'max-size': '10m'
'max-file': '5'
networks:
- traefik
depends_on:
- mysql
environment:
DATABASE_URL: mysql2://root:dummy#mysql/rails_blog_production
RAILS_SERVE_STATIC_FILES: 'true'
for more information, you can check this blog post
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).