dhd80
dhd80

Reputation: 625

Docker-Compose Environment-Variables blank string

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.

Upvotes: 47

Views: 132192

Answers (8)

Chris
Chris

Reputation: 21

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'

Upvotes: 0

Dara O h
Dara O h

Reputation: 149

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

Upvotes: 0

patricknelson
patricknelson

Reputation: 1245

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"

Upvotes: 17

Amitesh Singh
Amitesh Singh

Reputation: 183

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.

Upvotes: 3

Genovo
Genovo

Reputation: 591

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

Upvotes: 5

mxlhz
mxlhz

Reputation: 1138

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

Upvotes: 22

acran
acran

Reputation: 9018

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

Upvotes: 40

Marwane Ezzaze
Marwane Ezzaze

Reputation: 1057

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/

Upvotes: 7

Related Questions