`docker stack` subcommands: the `:?` interpolation operator and hyphens do not mix
维护者通常 1 天内回复
@Shubham-Padkonde 已经在做这个了。
开始于 2026年9月17日。
评估
调研方向
从 docker/cli/cli/compose/template/template.go 开始,重点查看 DefaultSubstitutionFuncs 和 hardDefault,并使用提供的 repro-hyphen.yml 通过 docker stack config 重现该行为。将其与 docker compose config 和控制文件进行比较。当 docker stack config 拒绝带连字符的 :? 消息,并报告必需变量错误而不是成功执行时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
Description
If a compose file processed by docker stack subcommands (deploy, config) contains an interpolation token of the form ${KEY:?hyphenated - message} then it is misinterpreted as if it were a different valid interpolation token: ${KEY- message}. This seems to be specific to docker stack -- docker compose does not exhibit the same issue.
Reproduce
No swarm or daemon required to demonstrate with docker stack config:
Files
repro-hyphen.yml:
services:
demo:
image: busybox
environment:
RESULT: ${UNSET_VARIABLE:?must be set - hyphen in this message}
repro-control.yml -- identical but for the hyphen:
services:
demo:
image: busybox
environment:
RESULT: ${UNSET_VARIABLE:?must be set; no hyphen in this message}
Demo
unset UNSET_VARIABLE
docker stack config -c repro-control.yml # correctly fails
docker stack config -c repro-hyphen.yml # incorrectly succeeds
docker compose -f repro-hyphen.yml config # correctly fails — same file
Expected behavior
docker stack config -c repro-hyphen.yml should fail, emitting a message such as the one docker compose emits:
error while interpolating services.demo.environment.RESULT: required variable UNSET_VARIABLE is missing a value: must be set - hyphen in this message
docker version
Client: Docker Engine - Community
Version: 29.4.3
API version: 1.54
Go version: go1.26.2
Git commit: 055a478
Built: Wed May 6 17:10:10 2026
OS/Arch: linux/arm64
Context: default
Server: Docker Engine - Community
Engine:
Version: 29.4.3
API version: 1.54 (minimum version 1.40)
Go version: go1.26.2
Git commit: 56be731
Built: Wed May 6 17:10:10 2026
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: v2.2.3
GitCommit: 77c84241c7cbdd9b4eca2591793e3d4f4317c590
runc:
Version: 1.3.5
GitCommit: v1.3.5-0-g488fc13e
docker-init:
Version: 0.19.0
GitCommit: de40ad0
docker info
Client: Docker Engine - Community
Version: 29.4.3
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.33.0
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v5.1.3
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 59
Running: 40
Paused: 0
Stopped: 19
Images: 53
Server Version: 29.4.3
Storage Driver: overlayfs
driver-type: io.containerd.snapshotter.v1
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Swarm: active
NodeID: cj4qpcbulk1pygy1qv3u8pejt
Is Manager: true
ClusterID: ia2ohfodbrxfj4za7k4cdnajl
Managers: 1
Nodes: 2
Default Address Pool: 10.0.0.0/8
SubnetSize: 24
Data Path Port: 4789
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 10
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Force Rotate: 0
Autolock Managers: false
Root Rotation In Progress: false
Node Address: <redacted>
Manager Addresses:
<redacted>
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 77c84241c7cbdd9b4eca2591793e3d4f4317c590
runc version: v1.3.5-0-g488fc13e
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.17.0-1013-aws
Operating System: Ubuntu 24.04.4 LTS
OSType: linux
Architecture: aarch64
CPUs: 8
Total Memory: 30.75GiB
Name: <redacted>
ID: <redacted>
Docker Root Dir: /opt/docker-data
Debug Mode: false
Experimental: false
Insecure Registries:
registry:5000
::1/128
127.0.0.0/8
Live Restore Enabled: false
Firewall Backend: iptables
Additional Info
It looks like this is related to the use of the DefaultSubstitutionFuncs array in docker/cli/cli/compose/template/template.go and the behavior of the hardDefault substitution function.
It also looks like this may generalize to a broader class of issues where a default value or error message in an interpolation token contains characters matching a different operator.
- 主要语言
- Go
- 星标
- 6.1k
- 派生
- 2.2k
- 平均合并
- 2 天 2 小时
- 30 天内合并 PR
- 28
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
docker/cli 的其他 Issue
-
[v29.9.0-rc.1 regression] e2e: TestRunAttachedFromRemoteImageAndRemove failing with v29.9.0-rc.1可能已有人在做 @thaJeztah 于 2 天前认领。 未关闭area/testing kind/bug
难度 2/5 1-3 小时 新手友好度 76/100
docker/cli#7352 · 3 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
`docker context export` writes a truncated tar archive可能已有人在做 @2arian3 于 11 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 92/100
维护者通常 1 天内回复
-
`docker logout docker.io` does not remove Docker Hub credentials可能已有人在做 @yin2hao 于 13 天前认领。 未关闭kind/bug status/0-triage
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 1 天内回复
-
Truncating log lines at 75 characters makes them useless.可能已有人在做 @locker95 于 55 天前认领。 未关闭kind/bug status/0-triage
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
cli-plugins/hooks: max-message enforcement is off by one可能已有人在做 @fallintoplace 于 133 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
难度 1/5 1-3 小时 新手友好度 90/100
FootprintAI/Containarium#2338 ·
维护者通常 1 天内回复
-
[Bug]: core doesn't build standalone on dev since a17068054 (go-mp3 require dropped, go.sum pruned)未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100
SagerNet/sing-openvpn#11 ·
-
priority: P3 type: devops
难度 2/5 1-3 小时 新手友好度 75/100
jiegui2025/hwspec#57 ·
维护者通常 1 天内回复