netikras
netikras

Reputation: 512

docker-compose .env file values with dollar: interpolated in MAC but not on Linux

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

Answers (1)

nicolas de loof
nicolas de loof

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

Related Questions