I'm trying to use env vars to define the host and credentials for the Traefik dashboard, but Traefik doesn't see them. All of the env vars are present when I verify them inside the docker container. Everything works well with hardcoded values. I attempted to use both approaches:
environment
section)All the other services of the docker-compose can successfully use the vars from the .env file
What am I doing incorrectly?
docker-compose.yml
version: '3.6'
services:
reverse-proxy:
image: traefik:v2.6
ports:
- 80:80
- 443:443
env_file:
- "./.env"
deploy:
placement:
constraints: [node.role == manager]
update_config:
failure_action: rollback
labels:
# Enable traefik for the specific service
- "traefik.enable=true"
# global redirect to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.middlewares=https-redirect"
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.https-redirect.redirectscheme.permanent=true"
# Make the Traefik use this domain in HTTPS
- "traefik.http.routers.traefik-https.rule=Host(`${TRFK_HOST}`)"
# Allow the connections to the traefik api for the dashboard support
- "traefik.http.routers.traefik-https.service=api@internal"
- "traefik.http.services.traefik-svc.loadbalancer.server.port=9999"
# Use the Let's encrypt resolver
- "traefik.http.routers.traefik-https.tls=true"
- "traefik.http.routers.traefik-https.tls.certresolver=le"
# Use the traefik_net network that is declared below
- "traefik.docker.network=traefik_net"
# Use the auth for traefik dashboard
- "traefik.http.middlewares.traefik-auth.basicauth.users=${TRFK_USER}:${TRFK_PSWD}"
- "traefik.http.routers.traefik-https.middlewares=traefik-auth"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefik-public-certificates:/certificates
command:
- --providers.docker
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
- --certificatesresolvers.le.acme.email=ex@ex.com
- --certificatesresolvers.le.acme.storage=/certificates/acme.json
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=http
- --accesslog
- --log
- --api
networks:
- traefik_net
volumes:
traefik-public-certificates:
networks:
traefik_net:
external: true
.env file
# traefik dashboard auth config
TRFK_USER=user
TRFK_PASSWD=$apr1$ZPapA6iQ$7OzhPqocYY.lotTdGgnoM.
TRFK_HOST=traefik.example.com
The only way that is currently working is:
env $(cat .env | grep ^[A-Z] | xargs) docker stack deploy -c docker-stack.yml stack
Is there any other way to make it work ?
You seem to be doing it correctly.
env_file:
and environment:
sections are used for injecting environment variables into the created container.
In this case, however, the environment variables are being expanded directly in the labels of the stack yml, so are not being passed through to the container - they do need to be part of the environment of the docker stack deploy
command.
As long as you have the call to docker stack deploy
wrapped up in a Makefile or bash script of some kind so preparing the environment is automated, this is the correct and necessary way.