[BUG] `docker compose config --no-interpolate` breaks when using `:` in variables and short-form volumes
Description
Example compose.yml
services:
test:
image: ubuntu:latest
volumes:
- ./${DIRECTORY:?error}/:/home/data
Here, I am using the interpolation that throws an error if DIRECTORY is empty (see docs)
When running docker compose config --no-interpolate, I would expect to see:
name: test
networks:
default:
name: test_default
services:
test:
image: ubuntu:latest
networks:
default: null
volumes:
- bind:
create_host_path: true
source: /home/user/test/${DIRECTORY:?error}
target: /home/data
type: bind
What I actually get:
name: test
networks:
default:
name: test_default
services:
test:
image: ubuntu:latest
networks:
default: null
volumes:
- bind:
create_host_path: true
source: /home/user/test/${DIRECTORY
target: ?error}
type: bind
There must be a naive splitting of the volume string by :, as it doesn't happen when using the required value that allows empty values, e.g
./${DIRECTORY?error}/:/home/data
produces the correct output
volumes:
- bind:
create_host_path: true
source: /home/user/test/${DIRECTORY?error}
target: /home/data
type: bind
Steps To Reproduce
- Use the above compose file
- Run
docker compose config --no-interpolate
Compose Version
Docker Compose version v2.28.1-desktop.1
Docker Environment
Client:
Version: 27.0.3
Context: desktop-linux
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.15.1-desktop.1
Path: /Users/normar1/.docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.28.1-desktop.1
Path: /Users/normar1/.docker/cli-plugins/docker-compose
debug: Get a shell into any image or container (Docker Inc.)
Version: 0.0.32
Path: /Users/normar1/.docker/cli-plugins/docker-debug
desktop: Docker Desktop commands (Alpha) (Docker Inc.)
Version: v0.0.14
Path: /Users/normar1/.docker/cli-plugins/docker-desktop
dev: Docker Dev Environments (Docker Inc.)
Version: v0.1.2
Path: /Users/normar1/.docker/cli-plugins/docker-dev
extension: Manages Docker extensions (Docker Inc.)
Version: v0.2.25
Path: /Users/normar1/.docker/cli-plugins/docker-extension
feedback: Provide feedback, right in your terminal! (Docker Inc.)
Version: v1.0.5
Path: /Users/normar1/.docker/cli-plugins/docker-feedback
init: Creates Docker-related starter files for your project (Docker Inc.)
Version: v1.3.0
Path: /Users/normar1/.docker/cli-plugins/docker-init
sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
Version: 0.6.0
Path: /Users/normar1/.docker/cli-plugins/docker-sbom
scout: Docker Scout (Docker Inc.)
Version: v1.10.0
Path: /Users/normar1/.docker/cli-plugins/docker-scout
Server:
Containers: 107
Running: 2
Paused: 0
Stopped: 105
Images: 211
Server Version: 27.0.3
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: ae71819c4f5e67bb4d5ae76a6b735f29cc25774e
runc version: v1.1.13-0-g58aa920
init version: de40ad0
Security Options:
seccomp
Profile: unconfined
cgroupns
Kernel Version: 6.6.32-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: aarch64
CPUs: 8
Total Memory: 7.755GiB
Name: docker-desktop
ID: 0a7123d2-ddf6-414f-88db-e89d232a13b1
Docker Root Dir: /var/lib/docker
Debug Mode: false
HTTP Proxy: http.docker.internal:3128
HTTPS Proxy: http.docker.internal:3128
No Proxy: hubproxy.docker.internal
Labels:
com.docker.desktop.address=unix:///Users/normar1/Library/Containers/com.docker.docker/Data/docker-cli.sock
Experimental: false
Insecure Registries:
hubproxy.docker.internal:5555
127.0.0.0/8
Live Restore Enabled: false
WARNING: daemon is not using the default seccomp profile
Anything else?
No response
There must be a naive splitting of the volume string by :
indeed, as variable syntax has many subtle rules, it makes it hard to split string without actual interpolation. Also volume could be set by a single variable to both declare source and destination, which would prevent expanding to "long syntax":
volumes:
- ${STRING}
Closing as "not planned". There's unfortunately no way to manage ambiguous : in short volume syntax when interpolation is disabled.
Wouldn't this be possible using a regex capture group?
- Find all variables using
(\$\{.*\}) - Sub them out with a standard alphanumeric string and create a mapping (e.g
$VAR1 -> ${DIRECTORY:?error}) - Do short to long form conversion as normal
- Re-substitute the variables using the mapping
I suppose as a workaround for users, this could be done outside of compose with another script.
nope, variables can be nested, which makes this way more complicated. Maybe feasible, but for a limited benefits.
What do you rely on config --no-interpolate for ?