49

I'm trying to get the Env-Variables in Docker-Compose to work. My Files:

env/test.env:

XUSER=you
XHOME=/home/${XUSER}

docker-compose.yml:

version: '3'
    services:
     abc:
        build: .
        image: xyz:latest
        container_name: xyz
        env_file:
          - env/test.env
        user: "${XUSER}"

docker-compose up --build

docker-compose config

WARNING: The XUSER variable is not set. Defaulting to a blank string.
    services:
      kernel:
        build:
          context: xyz
        container_name: xyz
        environment:
          XHOME: /home/you
          XUSER: you
        image: xyz:latest
        user: ''

As you can see user: '' is an empty string, but the env_file works. I found some old Bug reports about this issue, I'm not sure I doing something wrong or not.

8 Answers 8

43

Although the other answers are both correct they do not highlight the underlying misunderstanding here enough:

With the env_file option you can specify a file with variables to be injected into the environment in the container.

Using variable substitution in the docker-compose.yml you can access variables in the environment of the docker-compose command, i.e. on the host. You can set these using the usual mechanisms of your OS/shell, e.g. in bash:

export XUSER=you
docker-compose up

Additionally with docker-compose you can use a .env file in the current directory.

So in your concrete example you should just move env/test.env to .env to add the variables to the environment of docker-compose for variable substitution. If you also want to add them to the environment in the container you can do it like this:

version: '3'
services:
  abc:
    build: .
    image: xyz:latest
    container_name: xyz

    # add variables from the docker-compose environment to the container:
    environment:
      - XUSER=$XUSER
      # or even shorter:
      - XHOME

    # use variable from the docker-compose environment in the config:
    user: "${XUSER}"
Sign up to request clarification or add additional context in comments.

3 Comments

Note this also applies when using the --env-file command line option, e.g. docker compose --env-file file.env
And here I was, thinking the .env file allowed me to create variables that were local to the project and not pollute my entire setup AND be used in the docker-compose.yml files. Little did I realise it was about injecting into the container! Sigh!
Additionally to export it might be necessary to use the -E flag when utilizing sudo -E docker compose up
22

It says WARNING: The XUSER variable is not set. Defaulting to a blank string. because ${XUSER} doesn't exist at the time this is executed:

user: "${XUSER}"

${XUSER} is not in your environment (you can verify this by running: env | grep XUSER, which should output nothing), and docker-compose didn't find any .env file at the same level or no .env file was passed at the time you ran docker-compose up --build or docker-compose config

Flexible solution:

Rename env/test.env for .env and place it a the root of the folder container your docker-compose file so that docker automatically parses it.

Or use:

docker-compose --env-file path/to/env/test.env up --build
docker-compose --env-file path/to/env/test.env config

Permanent solution:

Export them manually in your environment by running:

export XUSER=you && export XHOME=/home/${XUSER}

Or you use your env/test.env file as a source (note that you'll need to prefix with 'export'):

env/test.env:

export XUSER=you
export XHOME=/home/${XUSER}

And then your run . /path/to/env/test.env or source /path/to/env/test.env

Comments

18

I also started encountering this after upgrading to Docker Desktop 4.12.0. This error started happening for quoted strings inside of .env (when using env_file to load variables in docker-compose.yml). In that case, be sure to use single quotes instead of double quotes, i.e.

MY_VAR='foo$bar'
# ... instead of...
MY_VAR="foo$bar"

6 Comments

Oh wow! This was it! Thanks @patricknelson I lost two hours trying to hunt this down.
I was constantly encountering a varying number of the following warning (which didn't disrupt functionality): WARN[0000] The "ce080nC1" variable is not set. Defaulting to a blank string.
IF no single or double quotes will work?
To expand on this a little, both MY_VAR="foo$bar" _and _MY_VAR=foo$bar will result in the warning WARN[0000] The "bar" variable is not set. Defaulting to a blank string.
this solved it for me. weird issue.
|
7

What you need to do is create .env file at the same directory as your docker-compose.yml file, the content of .env is :

XUSER=user1

then run docker-compose config

reference : https://docs.docker.com/compose/environment-variables/

2 Comments

Thanks for mentioning docker-compose config, very handy
This doesn't actually solve the problem. The problem is if the variable is something like XUSER=user1$foo then it will complain WARN[0000] The "foo" variable is not set.. So the solution is to sanitize the variable with a single quote: XUSER='user1$foo'
5

Since +1.28 .env file is placed in project root, not where docker-compose is executed. If you do that the variables will be automatically pulled through to be available to the container.

This works great in dev, especially with a a bind-mount volume to make .env available to compose in project root without also going into image build by including .env in .dockerignore

But in production I was not comfortable including it in my project root especially since I was pulling those project files down from github. The Compose file expects them to be in the production environment to replace for substitution SECRET_VAR=${SECRET_VAR}

So one hack solution was to stick the .env file high in my production directory tree, far away from my project (ideally these would come from an environment store on the hosting service, or another encrypted store), but inject those variables into the container at runtime by using the --env_file flag in Compose up.

The env_file flag works Like this: docker-compose -f docker-compose.prod.yml --env-file ../.env up -d

Its in the docs

Comments

5

Try this, I hope it will work.

  • You need to escape the variable if you want it to be expanded inside the container, using a double-dollar sign ($${envVariable}).

  • If however, you want it to be interpreted on your host, the $envVariable needs to be defined in your environment or in the .env file. The env_file option defines environment variables that will be available inside the container only.

1 Comment

The double-dollar sign save me !! Thank you
1
DB_PASSWORD="abc123$ABC"

I encountered this error when one of my .env file variables has "$" in its value, and the value enclosed in double quotes as shown above. Using single quotes for the variable (as shown below) resolved the issue.

DB_PASSWORD='abc123$ABC'

Comments

0

If there's a better way to do this please let me know but a hack is as follows for docker compose

To create dynamic .env files you can do the following

  1. create a cron job that runs at reboot eg:
    crontab -u $USER -e

  2. append the following oneliner or similar where every env variable is seperated by a \n. the sleep here just waits 30secs for an ip address to be assigned

  • @reboot sleep 30 && echo "MYIP=`ifconfig eth0 | grep "inet 10" | awk 'FNR==1{print $2}'`\nMYOTHERVAR=sometext" > <PATH TO DOCKER_COMPOSE FILE>/.env

  • This will update the .env file on every reboot and in this case the ip address and text variable will overwrite the contents of the .env file

  1. Then add

    env_file:
        - .env
    

to the docker-compose file

on reboot a file similar to the one below will be created

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.