Reputation: 512
test.yml
version: "3.1"
services:
test:
container_name: test
image: alpine
environment:
var: $test_variable
entrypoint: /bin/sh -c
command: [ "echo $$var" ]
test.env
test_variable=TE$T_VALUE3
command
docker-compose -f test.yml --env-file test.env up
Output [Linux]
Starting test ... done
Attaching to test
test | TE$T_VALUE3
test exited with code 0
Output [MacOS]
WARN[0000] The “T_VALUE3” variable is not set. Defaulting to a blank string.
WARN[0000] The “T_VALUE3" variable is not set. Defaulting to a blank string.
WARN[0000] The “T_VALUE3” variable is not set. Defaulting to a blank string.
[+] Running 2/2
:heavy_check_mark: test 1 layers [⣿] 0B/0B Pulled 3.4s
:heavy_check_mark: c41833b44d91 Pull complete 0.8s
[+] Running 2/0
:heavy_check_mark: Network test_default Created 0.0s
:heavy_check_mark: Container test Created 0.0s
Attaching to test
test | TE
test exited with code 0
Potentially related: https://github.com/docker/compose/issues/10419
Why the inconsistency? It feels as if docker-compose on Mac was loading the .env file into the test.yml (the compose config) before processing it.
Is this a known issue? How to get around it and make cross-platform env files?
Quoting the value also works differently: on Linux the value is then loaded as-is, i.e. with quotes, and on Mac it's loaded w/o quotes, but also w/o the $ interpolation (i.e. the same way it's loaded on Linux w/o quotes). So quoting is also not an option for a cross-platform approach...
I couldn't find any references discussing this inconsistency, or $
interpolation rules in .env files altogether.
EDIT 1
linux$ docker-compose -f test.yml --env-file test.env config
services:
test:
command:
- echo $$var
container_name: test
entrypoint: /bin/sh -c
environment:
var: TE$$$$T_VALUE3
image: alpine
version: '3.1'
macos$ docker-compose -f test.yml --env-file test.env config
name: test
services:
test:
command:
- echo $$var
container_name: test
entrypoint:
- /bin/sh
- -c
environment:
var: TE
image: alpine
networks:
default: null
networks:
default:
name: test_default
EDIT 2 [updated docker-compose on Linux to the latest version; same result]:
linux$ docker-compose --env-file test.env -f test.yml up
[+] Running 1/0
✔ Container test Recreated 0.0s
Attaching to test
test | TE$T_VALUE3
test exited with code 0
linux$
linux$ docker-compose --env-file test.env -f test.yml config
name: playground
services:
test:
command:
- echo $$var
container_name: test
entrypoint:
- /bin/sh
- -c
environment:
var: TE$$T_VALUE3
image: alpine
networks:
default: null
networks:
default:
name: playground_default
linux$
linux$ docker-compose --version
Docker Compose version v2.17.2
At least quoting the value now no longer treats quotes as part of the value:
linux$ docker-compose --env-file test.env -f test.yml up
[+] Running 1/0
✔ Container test Recreated 0.0s
Attaching to test
test | TE$T_VALUE3
test exited with code 0
linux$
linux$ cat test.env
test_variable='TE$T_VALUE3'
MacOS docker-compose version:
Docker Compose version 2.17.0
Still, the inconsistency of interpolating $ in unquoted values remains
Upvotes: 1
Views: 325
Reputation: 2633
To prevent interpolation on dot.env file values, you have to wrap those with single quotes:
$ cat .env
KEY='$2a$10$bY3ZpvQN/nTFHFSZjaZg1On50ueeibFctofVzk4uQu8gXPdkkyVZO'
$ cat compose.yaml
services:
foo:
image: alpine
env_file:
- .env
$ docker compose run foo | grep KEY
KEY=$2a$10$bY3ZpvQN/nTFHFSZjaZg1On50ueeibFctofVzk4uQu8gXPdkkyVZO
Why the inconsistency?
based on output format, your Linux installation runs Docker Compose v1 (soon to be EoL)
Upvotes: 1