使用 docker swarm stack 时,只有 Traefik 看不到 .env 文件中的环境变量

When using docker swarm stack, only Traefik does not see the env vars from the .env file

我正在尝试使用环境变量来定义 Traefik 仪表板的主机和凭据,但 Traefik 看不到它们。当我在 docker 容器中验证它们时,所有环境变量都存在。 一切都适用于硬编码值。 我尝试使用这两种方法:

docker-compose 的所有其他服务都可以成功使用 .env 文件中的变量

我做错了什么?

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 文件

# traefik dashboard auth config
TRFK_USER=user
TRFK_PASSWD=$apr1$ZPapA6iQOzhPqocYY.lotTdGgnoM.
TRFK_HOST=traefik.example.com

目前唯一可行的方法是:

env $(cat .env | grep ^[A-Z] | xargs)  docker stack deploy -c docker-stack.yml stack

还有其他方法可以让它发挥作用吗?

你似乎做对了。

env_file:environment: 部分用于将环境变量注入到创建的容器中。

然而,在这种情况下,环境变量直接在堆栈 yml 的标签中扩展,因此不会传递到容器 - 它们确实需要成为 [=12 环境的一部分=]命令。

只要您将对 docker stack deploy 的调用封装在 Makefile 或某种 bash 脚本中以便自动准备环境,这就是正确且必要的方法。