docker compose v2 config --no-interpolate should not escape environment variables
When checking the validity of a compose file with the docker compose config command, passing the --no-interpolate option to avoid interpolating environment variables, docker compose v2 turns all the $ characters into $$, making the normalized resulting compose file unable to later be provided with values for the environment variables.
This is different from the behaviour of docker-compose config v1 which was not escaping the environment variables dollar sign in that way.
Steps to reproduce the issue: 1.
$ cat compose_with_env_vars.yml
services:
service:
image: 'some.image/that/will/need/environment/variables:v1.0'
environment:
- MY_ENV_VAR=$ENV_VAR
$ docker compose --compatibility -f compose_with_env_vars.yml config --no-interpolate
services:
service:
environment:
MY_ENV_VAR: $$ENV_VAR
image: some.image/that/will/need/environment/variables:v1.0
Describe the results you received:
MY_ENV_VAR: $$ENV_VAR
Describe the results you expected:
MY_ENV_VAR: $ENV_VAR
Note that the --compatibility flag doesn't change that behaviour.
Output of docker compose version:
$ docker compose version
Docker Compose version v2.2.3
Output of docker info:
$ docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.7.1-docker)
compose: Docker Compose (Docker Inc., v2.2.3)
scan: Docker Scan (Docker Inc., v0.12.0)
Server:
Containers: 2
Running: 1
Paused: 0
Stopped: 1
Images: 49
Server Version: 20.10.12
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc version: v1.0.2-0-g52b36a2
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 5.4.0-99-generic
Operating System: Ubuntu 18.04.6 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 5.79GiB
Name: ubunturlututu
ID: DQFW:JUJT:P37M:BQTT:AVXP:SQJZ:ZV6Z:KYYY:BSYY:SJK6:HTQE:VT7W
Docker Root Dir: /var/lib/docker
Debug Mode: false
No Proxy: localhost,127.0.0.1
Username: *****
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
LinuxDev:5000
127.0.0.0/8
Live Restore Enabled: false
WARNING: No swap limit support
Behavior of docker-compose v1 for comparizon: 1.
$ docker-compose version
docker-compose version 1.27.4, build 40524192
docker-py version: 4.3.1
CPython version: 3.7.7
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
$ docker-compose --compatibility -f compose_with_env_vars.yml config --no-interpolate
services:
service:
environment:
MY_ENV_VAR: $ENV_VAR
image: some.image/that/will/need/environment/variables:v1.0
version: '3.9'
I have the same problem and have been trying to figure out what it is. After some research, it seems that it comes from the Convert function in pkg/compose/compose.go. This function calls escapeDollarSign and that's the reason why the $ is escaped. I compiled docker-compose without the call to escapeDollarSign and the behavior returned as in v1.
Great, thank you all.