Traefik not updating when services are deployed to docker swarm - docker

I have a traefik environment running in docker. Originally I was running services in standard containers. I am not deploying containers to docker swarm and I have done this for traefik too, where the container is only deployed to my swarm manager.
For some reason, traefik successfully registers the host name I have given it, and can access that fine.
However, when I deploy any other service to the swarm, traefik doesn't pick it up.
There is one other service that has partially worked. I have deployed heimdall to docker swarm which can be access from gateway.docker.swarm:8091 but I don't want the port either.
My traefik compose file is as follows:
version: '3.3'
networks:
swarm-network:
driver: overlay
services:
traefik:
# The official v2 Traefik docker image
image: traefik
deploy:
placement:
constraints:
- node.role == manager
labels:
- "traefik.enable=true"
- "traefik.docker.network=pi_swarm-network"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
- "traefik.http.routers.traefik.rule=Host(`traefik.docker.swarm`)"
# Enables the web UI and tells Traefik to listen to docker
command:
- '--api.insecure=true'
- '--providers.docker=true'
- '--providers.docker.swarmmode=true'
- '--providers.docker.defaultRule=Host("docker.swarm")'
- '--providers.docker.watch=true'
- '--providers.docker.swarmModeRefreshSeconds=15s'
# Metrics configuration for influx db.
- '--metrics=true'
- '--metrics.influxdb=true'
- '--metrics.influxdb.address=192.168.8.122:8086'
- '--metrics.influxdb.protocol=http'
- '--metrics.influxdb.database=traefik'
- '--metrics.influxdb.addEntryPointsLabels=true'
- '--metrics.influxdb.addServicesLabels=true'
- '--metrics.influxdb.pushInterval=10s'
# Tracing
- '--tracing=true'
- '--tracing.zipkin=true'
- '--tracing.zipkin.httpEndpoint=http://192.168.8.117:9411/api/v2/spans'
- '--log'
- '--accesslog'
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
networks:
- swarm-network
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
An example of another service I am running is heimdall which has the compose file of the following:
version: "3"
networks:
swarm-network:
external:
name: pi_swarm-network
services:
heimdall:
image: ghcr.io/linuxserver/heimdall
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/London
deploy:
placement:
constraints:
- node.labels.tier == web
labels:
- "traefik.enable=true"
- "traefik.docker.network=pi_swarm-network"
- "traefik.http.routers.heimdall.entrypoints=http"
- "traefik.http.services.heimdall.loadbalancer.server.port=8091"
- "traefik.http.routers.heimdall.rule=Host(`gateway.docker.swarm`)"
ports:
- 8091:80
restart: unless-stopped
networks:
- swarm-network
Can anyone see what I'm doing wrong?

I have figured out the problem.
In my compose file, I was using "traefik.http.services.heimdall.loadbalancer.entrypoints=http"
as well as
"traefik.http.routers.heimdall.entrypoints=http"
this was incorrect and needed to just be
"traefik.http.routers.heimdall.entrypoints=http"
For heimdall, I was also targetting the external port of 8091, whereas I actually needed to target the internal port of 80

Related

Traefik + cloudflared with full strict tunnel on docker

I have a VM which run multiple containers all linked to one docker network.
Traefik (as reverse proxy & load balancer)
cloudflared as tunnel
whoami (for testing purposes)
and some containers like photoprism, nextcloud, node-red,...
I generated an origin cert via Cloudflare which has been added to Traefik.
In Cloudflare, I have a subdomain which points via the tunnel to https://172.16.10.11 (ip from the VM). This causes an unsecure connection (IP SAN applied -> I don't think this is possible on a private ip?). When I disable TLS verification on Cloudflare, it works. However, I am trying to set this up properly. Next,I tried pointing my domain towards https://localhost. the cloudflared service running in a container cannot reach any other services as these are located other containers.
I was thinking, what if I run the cloudflared service within the Traefik container, I believe I can reach Traefik via localhost?
Do you have any advice on how to achieve a secure tunnel with cert verification? Or is this not realistic when self-hosting?
Current docker compose:
version: '3'
services:
traefik:
image: traefik:latest
command:
- --log.level=debug
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --serverstransport.insecureskipverify
- --providers.file.filename=/etc/traefik/dynamic_conf.yml
- --providers.file.watch=true
ports:
- "8080:8080"
- "443:443"
- "80:80"
networks:
- proxy_network
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefik-data:/etc/traefik
labels:
- traefik.enable=true
- traefik.docker.network=proxy_network
- traefik.http.routers.traefik.rule=Host(`${DOMAINNAME_TRAEFIK}`)
- traefik.http.routers.traefik.entrypoints=web
- traefik.http.routers.traefik.service=traefik
- traefik.http.services.traefik.loadbalancer.server.port=8080
tunnel:
container_name: cloudflared-tunnel
image: cloudflare/cloudflared
#restart: unless-stopped
networks:
- proxy_network
command: tunnel --no-autoupdate run --token ${CLOUDFLARED_TOKEN}
whoami:
image: traefik/whoami
container_name: whoami1
command:
# It tells whoami to start listening on 2001 instead of 80
- --port=2000
- --name=iamfoo
networks:
- proxy_network
labels:
- traefik.enable=true
- traefik.http.routers.whoami.rule=Host(`${DOMAINNAME}`)
- traefik.http.routers.whoami.entrypoints=websecure
- traefik.http.routers.whoami.tls=true
- traefik.http.routers.whoami.service=whoami
- traefik.http.services.whoami.loadbalancer.server.port=2000
volumes:
traefik-data:
driver: local
networks:
proxy_network:
name: proxy_network
external: true
I expect a secure tunnel solution and to make sure that this architecture is setup in a good way.

ioBroker with Node-RED behind traefik on Synlogy NAS with Docker

To control some Tasmota driven WiFi Sockets and some other stuff I want to install a Docker based SmartHome central on my Synology DS218+.
This installation is to be reachable only from inside my LAN while some other Docker containers on my NAS are accessible from the Internet.
So I decided to use a docker-compose Setup based on a Traefik-script with one single Traefik-container and a SmartHome-script with some SmartHome related containers (both scripts see below).
During a step-wise installation I first implemented the ioBroker container, finished the initial Setup and installed the Node-RED adapter.
After that I added a Mosquitto container to my SmartHome-script and a dependency to let the ioBroker container start after Mosquitto.
All containers of the above setup come up without any problems but ioBroker is the only Service that's accessible.
Whether my Tasmota-deices nor ioBroker seem to have access to Mosquitto and when I try to start the Node-RED-instance, I get an Error "404 page not found"
Traefik-script:
version: "3.9"
services:
traefik:
image: traefik:v2.4
command:
- --log.level=ERROR
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=web-secure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web-secure.address=:443
- --entrypoints.web-secure.http.tls.certresolver=lets-encrypt
- --entrypoints.something.address=:1234
...
- --entrypoints.node-red.address=:1880
- --entrypoints.mosquitto.address=:1883
- --entrypoints.iobroker.address=:8081
...
- --entrypoints.something-different.address=:23456
- --entrypoints.something-different.http.redirections.entrypoint.to=something-different
- --entrypoints.something-different.http.redirections.entrypoint.scheme=https
- --providers.docker=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.file.directory=/etc/traefik/dynamic/
- --providers.file.watch=true
- --certificatesresolvers.lets-encrypt.acme.email=my.email#internet.com
- --certificatesresolvers.lets-encrypt.acme.storage=/etc/traefik/acme.json
- --certificatesresolvers.lets-encrypt.acme.tlschallenge=true
restart:
- unless-stopped
ports:
- 80:80
- 443:443
- 1234:1234
...
- 1880:1880
- 1883:1883
- 8081:8081
...
- 23456:23456
volumes:
- /etc/localtime:/etc/localtime:ro
- ${PWD}/traefik:/etc/traefik
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
- traefik.enable=false
networks:
- traefik
networks:
traefik:
external: false
driver: bridge
name: traefik
SmartHome-script
version: "3.9"
services:
mosquitto:
image: eclipse-mosquitto:latest
restart:
- unless-stopped
volumes:
- ${PWD}/mosquitto-config:/mosquitto/config
- ${PWD}/mosquitto-data:/mosquitto/data
- ${PWD}/mosquitto-log:/mosquitto/log
labels:
- traefik.enable=true
- traefik.tcp.routers.mosquitto.entrypoints=mosquitto
- traefik.tcp.routers.mosquitto.rule=HostSNI(`my.synology.nas.local`)
- traefik.tcp.routers.mosquitto.service=svc-mosquitto
- traefik.tcp.services.svc-mosquitto.loadbalancer.server.port=1883
networks:
- traefik
iobroker:
image: iobroker/iobroker:latest
restart:
- unless-stopped
depends_on:
- mosquitto
environment:
- LANG=de_DE.UTF‑8
- LANGUAGE=de_DE:de
- LC_ALL=de_DE.UTF-8
- TZ=Europe/Berlin
volumes:
- ${PWD}/iobroker-data:/opt/iobroker
labels:
- traefik.enable=true
- traefik.http.routers.iobroker.entrypoints=iobroker
- traefik.http.routers.iobroker.rule=Host(`my.synology.nas.local`)
networks:
- traefik
networks:
traefik:
external: true
I suspect that the inaccessible Mosquitto-server is related to the "labels" section of the Mosquitto-container, because this is the first time I try to use TCP routing.
The inaccessible Node-RED instance within ioBroker might be related to using more than one HTTP-port with this container but I have no idea, where to begin troubleshooting.
What's the "correct way" to handle such use cases in docker-compose scripts respectively in Traefik?
Thanx in advance for your hints!
Lanzi

Traefik routing one application to port 80, others require explicit port

I have an environment running docker containers.
This environment hosts Traefik, Nextcloud, MotionEye and Heimdall.
I also have another environment running CoreDNS in a docker container.
For some reason, I can get MotionEye to be accessible from motioneye.docker.swarm (changed the domain in here for privacy).
However, for nextcloud and Heimdall, I have to explicitly access the ports and I'm struggling to tell why.
e.g. Heimdall is gateway.docker.swarm:8091 when should be gateway.docker.swarm
When a user requests a webpage onto the local dns server X.X.X.117 it gets routed through to the traefik instance on X.X.X.106.
My traefik compose file is as follows:
version: '3'
services:
reverse-proxy:
# The official v2 Traefik docker image
image: traefik:v2.3
restart: always
# Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
labels:
- "traefik.port=8080"
- "traefik.backend=traefik"
- "traefik.frontend.rule=Host:traefik.docker.swarm"
- "traefik.docker.network=traefik_default"
My Heimdall compose is as follows:
version: "3"
services:
heimdall:
image: ghcr.io/linuxserver/heimdall
container_name: heimdall
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/London
volumes:
- /home/pi/heimdall/config:/config
ports:
- 8091:80
restart: unless-stopped
networks:
- heimdall
labels:
- "traefik.enable=true"
- "traefik.port=8091"
- "traefik.http.routers.heimdall.entrypoints=http"
- "traefik.http.routers.heimdall.rule=Host(`gateway.docker.swarm`)"
networks:
heimdall:
external:
name: heimdall
Can anyone see what I'm doing wrong here?
When you access through gateway.docker.swarm:8091 it works because you are accessing the heimdall container directly. This is possible because you defined
ports:
- 8091:80
in your docker-compose.
In order to access through traefik they must be on the same network. Also, remove the port mapping if you like this container to be only accessible through traefik. And finally correct the traefik port accordingly.
version: "3"
services:
heimdall:
image: ghcr.io/linuxserver/heimdall
container_name: heimdall
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/London
volumes:
- /home/pi/heimdall/config:/config
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.port=80"
- "traefik.http.routers.heimdall.entrypoints=http"
- "traefik.http.routers.heimdall.rule=Host(`gateway.docker.swarm`)"

Traefik with Docker Swarm?

I am not sure if this is possible because I do not have control over the DNS (I can edit /etc/hosts though).
I have a few Azure Ubuntu servers running with 1 manager and 2 workers (3 total). These nodes are only accessible on our corporate network. I typically access web portals from my desktop at the office by typing:
IP-Address:Port
Host:Port
Host.corp.companyname.com:Port
My goal is to instead type something like host/pgadmin or host/portainer to be routed to a web portal which is running on the worker nodes. Is it possible? I don't mind editing my desktop's /etc/hosts file but I don't want to specify an IP address (otherwise there is no point in having the portal run on multiple nodes).
services:
web:
image: traefik:1.7-alpine
networks:
- frontend
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
ports:
- "80:80"
- "8080:8080"
command:
- --docker
- --docker.swarmMode
- --docker.domain=corp.companyname.com
- --docker.watch
- --api
- --defaultentrypoints=http
deploy:
placement:
constraints:
- node.role == manager
pgadmin4:
image: dpage/pgadmin4:4.0
ports:
- "5050:80"
deploy:
placement:
constraints:
- node.role == worker
labels:
- traefik.enable=true
- traefik.docker.network=frontend
- traefik.backend=pgadmin4
- traefik.port=5050
- traefik.frontend.rule=???????
networks:
- frontend
networks:
frontend:
external: true
name: frontend
You can totally do it with
- traefik.frontend.rule=PathPrefixStrip:/pgadmin/
Here is a list of matchers that traefik can work with.
I got this to work finally.
I had to rename my traefik.docker.network from frontend to traefik_frontend (traefik was the name I used when I ran the stack deploy command)
I had to use Firefox (Chrome would not work - I have no idea why)
I changed the traefik.port=5050 to traefik.port=80
I added traefik-pgadmin.docker.localhost to my /etc/hosts file on windows (and noticed before I was saving it as .txt file which was wrong)

How can I secure the traefik dashboard using SSL & basic auth?

A have traefik set up and working for a 3 node docker swarm on DigitalOcean, and my web apps are being served just fine. I want to secure the traefik dashboard, and have gleaned some info from GitHub issues, but my attempts result in a gateway timeout when trying to access the dashboard.
My compose file is below (auth & url edited for security):
version: "3.5"
services:
traefik:
image: traefik:1.6
command:
- --api
- --docker
- --docker.watch
- --docker.swarmmode
- --entryPoints=Name:http Address::80
- --entryPoints=Name:https Address::443 TLS:/run/secrets/el_cert,/run/secrets/el_key,/run/secrets/as_cert,/run/secrets/as_key
ports:
- 80:80
- 443:443
networks:
- proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
secrets:
- as_cert
- as_key
- el_cert
- el_key
deploy:
mode: global
labels:
- "traefik.frontend.entryPoints=http,https"
- "traefik.frontend.headers.SSLRedirect=true"
- "traefik.frontend.rule=Host:<hostname>"
- "traefik.port=8080"
- "traefik.frontend.auth.basic=<user>:<password>"
placement:
constraints: [node.role==manager]
networks:
proxy:
external:
name: proxy
secrets:
as_cert:
external: true
as_key:
external: true
el_cert:
external: true
el_key:
external: true
BTW If I move the labels out from under deploy it works locally using docker-compose.
Adding the following label seems to fix things:
traefik.backend.loadbalancer.swarm=true
I presume the traefik load balancer was getting into some kind of infinite loop. I would be grateful if someone could offer a full explanation!

Resources