Docker-Compose Environment-Variables blank string

Viewed 47415

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.

6 Answers

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}"

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

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

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.

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"
Related