Environment variables in static config dynamic config not working, traefik v3

my .env file in the traefik-stack folder looks something like:

TRAEFIKADMINCREDS='user:hashedpass'
EMAILFORRESOLVER='user@email.com'
DOMAIN='example.com'
CROWDSEC_BOUNCER_API_KEY='foo'

In my docker-compose.yml I know I can simply...

      - traefik.http.routers.traefik-https.rule=Host(`hostname.${DOMAIN}`)```

and the above works... I have also attempted to declare environment variables in docker-compose.yml like this:

    environment:
      - DOMAIN=${DOMAIN}
      - CROWDSEC_BOUNCER_API_KEY=${CROWDSEC_BOUNCER_API_KEY}

In the above example, I'm concerned that perhaps the declared variables being the the same is an issue? ie: MYDOMAIN=${DOMAIN} better than DOMAIN=${DOMAIN} ?

I have not been able to get .env variables working in either my static (traefik.yml) or dynamic configs (dynamic_config.yml).

In my static (traefik.yml):

    acme:
      email: {{ env "EMAILFORRESOLVER" }} 
    #  email: {{ env "emailforresolver" }} 
    #  email: {env "emailforresolver"}

In my dynamic config (dynamic_config.yml) something like:

    proxmox-https:
      rule: "Host(`hostname.{{ env "DOMAIN" }}`)"
      # rule: "Host(`hostname.{{ env "domain" }}`)"
      # rule: "Host(`hostname.{ env "DOMAIN" }`)"
      # rule: "Host(`hostname.{ env "domain" }`)"

I'm not sure what I'm doing wrong, but I'm beating my head agains a wall trying to get .env variables in my static and dynamic config files. What is the correct way to format and method to insert env variables to these files? Also, does v3 do this different from v2? Please help! I've attempted read the documentation on this but I'm quite confused about it. Perhaps when I get this working I have a question about secrets too.

Found this post while I was searching how to do the same thing. I found the answer in this post:

Also note that you can't use go templating (.env variables) in the static traefik config file. Only dynamic files as noted on this page:

Hope this helps you, and others in the future find the answer more easily.

1 Like

So, I guess my confusion is how are the environment variables declared? In the attached link example... they're doing...

docker-compose.yml

 ...
    environment:
      # WAN_HOSTNAME is used in traefik config.yml file !
      - WAN_HOSTNAME

However, I've seen conflicting forum ideas on how this is done, I've seen it done this way (above), then seen that others say you need to 'declare' (below), linked post suggests the below is incorrect?:

docker-compose.yml

 ...
    environment:
      # WAN_HOSTNAME is used in traefik config.yml file !
      - WAN_HOSTNAME=${WAN_HOSTNAME}

Am I understanding this correctly?
It also seems this NEEDS to match an exact variable named WAN_HOSTNAME in the .env file? ie from

.env:

WAN_HOSTNAME='example.com'
ANOTHER_VARIABLE='foo'

You declare the environment variables in the .env file and reference them in the compose file so the container can use them in the dynamic config files. I just tested both ways you referenced for docker-compose.yml and both work. However you pass the variable through the compose file - WAN_HOSTNAME= is how you will reference it in Traefik's dynamic config file.

.env

WAN_HOSTNAME='example.com'
ANOTHER_VARIABLE='foo'

docker-compose.yml
- WAN_HOSTNAME would be referenced in dynamic_config.yml as {{env "WAN_HOSTNAME"}}
- WAN_HOSTNAME=${WAN_HOSTNAME} would be referenced in dynamic_config.yml as {{env "WAN_HOSTNAME"}}
- HOSTNAME=${WAN_HOSTNAME} would be referenced in dynamic_config.yml as {{env "HOSTNAME"}}

All would result in the same value of example.com from the .env file.

Here's an example of my setup:

.env

...
## Host IP Address
HOST_IP=192.168.0.10
## Domain Name
DOMAIN=mydomain.com
...

compose.yaml (for Traefik)

...
environment:
      - HOST_IP
      - DOMAIN
...

traefikDynamicConfig.yaml

http:
  routers:
    traefikInternal:
      rule: Host(`{{env "HOST_IP"}}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
      entrypoints: websecure
      middlewares:
      service: api@internal
    traefikExternal:
      rule: Host(`traefik.{{env "DOMAIN"}}`)
      entrypoints: websecure
      middlewares:
      service: api@internal

I hope this helps a bit more to understand.

This works for dynamic config, however, the same does not work in the static config. Am I missing something here?

dynamic_config.yml (in dynamic config, is working)

...
      rule: Host(`portainer.{{env "DOMAIN"}}`)
...

traefik.yml (static config, the below is working)

...
    acme:
      email: ${VAR_EMAILFORRESOLVER}
...

Correct, this does not work in the static file. See here: Traefik File Documentation - Traefik

My solution to this was using environment settings for my traefik static config in the traefik compose.yaml. this way I could use .env variables with ${variable}. I can post an example later when at my PC if you want.

One note, is you can't mix static config implementations. Meaning choose one of traefik.yaml or compose environment or cli arguments.
Read: Traefik Configuration Documentation - Traefik

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.