Compose: strange interpretation/parsing of .env file

Created on 7 Jul 2016  路  5Comments  路  Source: docker/compose

In native Max OS / Unix normally you can write:

MY_ENV_VAR1=abcdef
MY_ENV_VAR2="abcdef"

and both env vars will be equal (double quotes are omitted/ignored). Also libraries I know that use (parse) .env files work in a same way.

Docker compose however treats double quotes differently when parsing .env file passed as env_file: .env in docker-compose.yml. It does not ignore double quotes and treats them as a part of the string.

Is it intentional behaviour or it's a bug? Tested on docker-compose version 1.5.2, build 7240ff3.

kinquestion

Most helpful comment

Here's an improved sed invocation, which will ignore "=" characters in a variable's value:

sed -e 's/="\(.*\)/=\1/g' -e 's/"$//g'

...or if you need to add quotes:

sed -e 's/=\(.*\)/="\1/g' -e 's/$/"/g'

This is useful if you want to keep the file in the broken, unquoted docker format, but use it somewhere else in a shell script. E. g., this will export all variables in the file:

export $(sed -e 's/=\(.*\)/="\1/g' -e 's/$/"/g' env.docker | xargs)

All 5 comments

It's the same behaviour as the Docker CLI, i.e. docker run --env-file. It would need to be fixed there before being fixed in Compose, because we try to keep behaviour exactly the same.

$ cat test.env
MY_ENV_VAR1=abcdef
MY_ENV_VAR2="abcdef"

$ docker run --env-file=test.env alpine sh -c 'echo $MY_ENV_VAR1'
abcdef

$ docker run --env-file=test.env alpine sh -c 'echo $MY_ENV_VAR2'
"abcdef"

You might want to check docker/docker to see if there's already an issue about it. I found https://github.com/docker/docker/issues/12997, which is currently closed, but if there are other env file parsers out there with different behaviour, there's a strong case for us keeping parity with them.

env_file are for containers, ./.env is for docker-compose. The compose variables, I know interpret quotes literally. This might be an advantage, as you don't have to worry about glob.

Alternatively, you can parse these out using a wrapper script to bootstrap your container to get full shell interpolation with your envfile, e.g. cat my_shell_envfile | xargs -n 1 export. If need extra shell features like subshells, e.g. START=$(date) then you'll need to re-interpolate it with eval before the export command.

Just to convert the bash env.sh to env.docker:

$ sed -e "s/=\"/=/g" -e "s/\"$//g" env.sh > env.docker

It is annoying docker and docker-compose do not follow the same standard as shell.

Here's an improved sed invocation, which will ignore "=" characters in a variable's value:

sed -e 's/="\(.*\)/=\1/g' -e 's/"$//g'

...or if you need to add quotes:

sed -e 's/=\(.*\)/="\1/g' -e 's/$/"/g'

This is useful if you want to keep the file in the broken, unquoted docker format, but use it somewhere else in a shell script. E. g., this will export all variables in the file:

export $(sed -e 's/=\(.*\)/="\1/g' -e 's/$/"/g' env.docker | xargs)

sed -e 's/=\(.*\)/="\1/g' -e 's/$/"/g' env.docker won't work properly on file containing empty strings and comments.

export $(sed -e 's/=\(.*\)/="\1"/g' env.docker | grep -v "#" | xargs) would be a good alternative

Was this page helpful?
0 / 5 - 0 ratings