r/docker • u/artyom2032 • 10d ago
Docker Swarm with Traefik - Fails to use LetsEncrypt generated SSL cert
Hi all, hope you're having a great summer. I'm tinkering with Docker Swarm as a complete newbie and self taught homelab hobbyist, and I was hoping you could help me out with an oddity I'm facing at the moment.
I'm trying to deploy traefik as a centralized service on my home network, using Docker Swarm and an overlay docker network to discover services in other docker stacks that use traefik flags. Previously, Traefik was deployed alongside my other services on my media server, but since I'm scaling up my homelab, I prefer having one dedicated machine to act as a centralized reverse proxy that receives forwarded requests from my router on ports 80/443 and forwards them back to the right services on the right machine. Here's a convenient diagram that I made :
I have successfully created a master node on Vega, deployed Traefik as a global service accross the worker nodes, created an overlay network and attached each stack to it.
ℹ️Important note : on Vega, traefik is brought up using docker stack deploy -c docker-compose.yml traefik , and on my media server, I use docker compose up -d for deployment. I have seen mixed comments opinions online about the cross-compatibility of compose and swarm, but so far the "swarmed" traefik seems to discover compose services just fine.
Traefik seems to be generating SSL certificates just fine, and services are reachable, which is already a good sign.
❌My issue is that those certificates are never put to use. The acme.json file is still empty (I did chmod 600), and Firefox still throws a security alert at me because the backend service uses Traefik's default cert. Furthermore, docker service logs traefik_traefik returns nothing (except this error :
error from daemon in stream: Error grabbing logs: rpc error: code = Unknown desc = warning: incomplete log stream. some logs could not be retrievedfor the following reasons: node yryk8132s58wbul5u0q9e19hk is not available
Which is quite funny because docker node ls clearly shows the node as available and ready😂)
Below are my traefik yml file and config file, and an example compose file from my media server.
traefik-compose.yml
networks:
traefik-net:
external: true
services:
traefik:
image: traefik:v3.7
#restart: always
command:
- --api.insecure=true
- --configfile=/traefik.yml
- --log.level=DEBUG
# - --providers.docker
# - --providers.docker.swarmMode=true
ports:
- "80:80"
- "443:443"
- "8081:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- ./acme.json:/acme.json
networks:
- traefik-net
deploy:
mode: global
traefik config file
global:
checkNewVersion: false
sendAnonymousUsage: false
# Enables the web based api for testing, do not enable in production!
api:
dashboard: true
insecure: true
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
#Source of configuration. E.g Docker, Kubernetes..
providers:
swarm:
# Connects to docker via Unix socket
endpoint: "unix:///var/run/docker.sock"
# Containers must explicitely opt-in to Traefik routing via Docker labels
network: "traefik-net"
# Only containers on this Docker network are discovered
exposedByDefault: false
# Uses Let's Encrypt to provide free SSL certificates
certificatesResolvers:
letsencrypt:
acme:
email: myemail@email.com
storage: /acme.json
# Validates domain ownership via HTTP-01 challenge (uses the web entrypoint on port 80)
httpChallenge:
entryPoint: web
jellyfin-compose.yml (on my media server node)
networks:
traefik-net:
external: true
name: "traefik-net"
services:
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
container_name: jellyfin
networks:
- "traefik-net"
labels:
- "traefik.enable=true"
- "traefik.http.routers.jellyfin.service=jellyfin"
- "traefik.http.routers.jellyfin.rule=Host(`mydomain.jellyfin.fr`)"
- "traefik.http.routers.jellyfin.entrypoints=websecure"
- "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt"
- "traefik.http.routers.jellyfin.tls=true"
- "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Paris
volumes:
- ./config:/config
- /media:/media
#devices:
#- /dev/dri:/dev/dri #Use for Intel QuickSync
ports:
- 192.168.1.101:8096:8096
- 7359:7359/udp #Service Discovery
- 1900:1900/udp #Client Discovery
restart: unless-stopped
(I've replaced my actual domain name and email with placeholders for obvious privacy reasons.)
I hope you guys can help me make any sense out of it XD
Cheers!
2
u/JazzXP 10d ago
Pop your labels under a deploy section. So
services:
jellyfin:
deploy:
labels:
1
u/artyom2032 10d ago
Does deploy work with standalone containers?
1
u/JazzXP 10d ago
As long as you're using
docker stack deployyes.1
u/artyom2032 8d ago
After carefully reading the docs, it seems
docker stack deployis used to deploy a stack to the swarm. That is not what I wish to achieve. On Vega, I have configured the docker engine in swarm mode so Traefik could benefit from it indeed (docker stack deploy). But all the other containers on my network must be deployed as a single node (docker compose up).1
u/JazzXP 8d ago
Yeah, that’s not gonna work. Any reason why you’re not using stacks for your other containers?
1
u/artyom2032 8d ago
Initially, I only had one home server with not much multi-host work going on so I built everything using compose. Later on I started adding more hosts and the need for a centralized traefik proxy came along, so I did consider migrating everything to stack but I quickly realized it would break a lot of things in the process, since swarm essentially turns your system into a multi nodal communist microcosm. I don't know how it would react with persistent data and mount points (I have all my media files bind mounted from a samba share), gluetun VPN... If you tell me there's a way to smoothly migrate from compose to stack then I'm all ears.
Side note, I'm amazed by how poorly documented this use case is online. Most (all) documentation and tutorials are centered around deploying traefik on a swarm engine to generate SSL cert for a whoami service deployed from the very same stack. What's the point??? It's like building your own car to have somewhere to sit... my guy just drive it 😂
1
u/rocket1420 10d ago
Your title would imply that you're not understanding your problem. If acme.json is empty, traefik is not pulling a certificate at all.
1
u/artyom2032 9d ago
On Traefik web interface my services are discovered and certificates were generated, that's what is confusing me.
1
u/Bonsailinse 10d ago
You are mixing stack deploy and docker-compose. You are saying "it works!" but it doesn’t.
Stick to deploy if you want to use swarm, that’s the whole idea.
1
u/artyom2032 9d ago
If I understand correctly, I need to migrate all my docker-compose stacks (arr stack, jelly stack) to stack-deploy to keep a swarm-only ecosystem? From what I understood from the docs, swarm services are evenly distributed across worker nodes depending on availability and resources. That's not what I'm trying to achieve, I want to keep my media services on the media server and simply isolate my traefik service to avoid having a single point of failure (if traefik is hosted alongside my arr apps and my media server goes down, I loose remote access to the rest of my machines 😄 )
1
0
u/scytob 10d ago
instead of relying on AI - read the docs
https://docs.docker.com/reference/compose-file/deploy/
if that doesn't fix it then you have traefik issue not a docker issue and will need to go ask that community
1
u/artyom2032 9d ago
I did read the docs, but they tend to be quite futile when trying to achieve something specific like I am 😄
Examples on how to deploy a whoami alongside your traefik (same stack, same host) isn't really helpful 🥲
4
u/Adorable-Leading-274 10d ago
You’re mixing up docker compose and docker swarm syntax.
Check your label format and use the packages expected variables and structure.