Reputation: 625
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
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
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
create a cron job that runs at reboot eg:
crontab -u $USER -e
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
Then add
env_file:
- .env
to the docker-compose file
on reboot a file similar to the one below will be created
Upvotes: 0
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
Reputation: 183
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
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
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
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
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
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
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