traefik icon indicating copy to clipboard operation
traefik copied to clipboard

Support for Docker Secrets in label values

Open devantler opened this issue 3 years ago • 3 comments

Welcome!

  • [X] Yes, I've searched similar issues on GitHub and didn't find any.
  • [X] Yes, I've searched similar issues on the Traefik community forum and didn't find any.

What did you expect to see?

I have not found it possible to use secrets for label values when deploying with docker. For me, there are two reasons why it would be nice if that were possible:

  1. We can hide sensitive information we do not want to expose to others, e.g., domain names.
  2. We can create deployable compose files that only require the person deploying the file to set its secrets. Such an approach simplifies maintaining stacks and deploying stacks. It would, for example, allow stacks to be deployed to many different Portainer instances without making edits to the files first.

devantler avatar Jan 14 '22 03:01 devantler

Hello @niem94 and thanks for your interest in Traefik,

Are you talking about Swarm secrets? Which dynamic configuration options should not be exposed, and hence should be stored in secrets?

Maybe what you are looking for, is a way to template Docker compose files? If that's the case, this can be done by using environment variables (see https://docs.docker.com/compose/environment-variables/).

kevinpollet avatar Jan 14 '22 16:01 kevinpollet

Oh, I was not aware this was possible. I will test it out and see if it will do the trick.

Closing the issue for now.

devantler avatar Jan 14 '22 17:01 devantler

This was definitely useful. Thanks for pointing me in that direction.

For anyone interested, it requires the following workaround for docker swarm as .env is not officially supported with docker-compose:

docker stack deploy -c <(docker-compose -f docker-compose.traefik.yml config) traefik

This resolves all .env variables in the stack file if a .env file is present at the root of the project. The result is passed on to docker stack deploy, which deploys the stack as usual.

Below is the unprocessed stack file used in the above command.

version: '3.8'

services:

  traefik:
    image: traefik:${TRAEFIK_VERSION:-v2.6}
    command:
      # Docker swarm configuration
      - --providers.docker=true
      - --providers.docker.swarmMode=true
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=public
      # Configure entrypoint
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.wireguard.address=:51820/udp
      # SSL configuration
      - --certificatesresolvers.letsencrypt.acme.dnschallenge=true
      - --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
      - --certificatesresolvers.letsencrypt.acme.email=${EMAIL:?}
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
      # Redirect to HTTPS
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https
      # Enable dashboard
      - --api.dashboard=true
      # Enable Traefik Pilot
      - --pilot.token=${TRAEFIK_PILOT_TOKEN}
    environment:
      # CloudFlare specific letsencrypt environment variables (https://go-acme.github.io/lego/dns/cloudflare/)
      CF_API_EMAIL: ${EMAIL:?The EMAIL environment variable was not set.}
      CF_DNS_API_TOKEN: /run/secrets/cloudflare_dns_api_token
    ports:
      - 80:80
      - 443:443
      - 51820:51820/udp
    networks:
      - public
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - letsencrypt:/letsencrypt
    secrets:
      - cloudflare_dns_api_token
    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        traefik.enable: "true"
        traefik.http.routers.traefik.rule: "Host(`${TRAEFIK_SUBDOMAIN:-traefik}.${DOMAIN:?}`)"
        traefik.http.routers.traefik.entrypoints: "websecure"
        traefik.http.routers.traefik.tls.certresolver: "letsencrypt"
        traefik.http.routers.traefik.service: "api@internal"
        traefik.http.services.traefik.loadbalancer.server.port: 8080
        traefik.http.routers.traefik.middlewares: "auth"
        traefik.http.middlewares.auth.basicauth.users: "${TRAEFIK_HTPASSWD:-admin:$apr1$o02QvmB8$BzTRdAsEXSOWAH7AtIgjh0}"
networks:
  public:
    external: true

volumes:
  letsencrypt: null
secrets:
  cloudflare_dns_api_token:
    external: true

devantler avatar Jan 14 '22 19:01 devantler

how do I do it using portainer?

ciocan avatar Jul 18 '24 09:07 ciocan