docker-bake.json applying HCL string templates
Contributing guidelines
- [X] I've read the contributing guidelines and wholeheartedly agree
I've found a bug and checked that ...
- [X] ... the documentation does not mention anything about my problem
- [X] ... there are no open or closed issues that are related to my problem
Description
When using docker bake with a JSON docker bake config, strings are being parsed as if they were HCL strings (applying HCL string template interpolation / directives).
Expected behaviour
Expected the JSON file to be parsed as a JSON file, such that strings on it are not further processed as HCL templates. In the example below, I expect the image to be build and labeled with the foo label getting the literal value %{bar}.
Actual behaviour
On the example below, parsing the docker-bake.json fails, as it tries to parse as HCL template.
Buildx version
github.com/docker/buildx v0.13.0 0de5f1c
Docker info
docker info
Client: Docker Engine - Community
Version: 25.0.4
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.13.0
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.24.7
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 14
Running: 0
Paused: 0
Stopped: 14
Images: 55
Server Version: 25.0.4
Storage Driver: overlay2
Backing Filesystem: btrfs
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: d2d58213f83a351ca8f528a95fbd145f5654e957
runc version: v1.1.12-0-g51d5e94
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.7.11-orbstack-00143-ge6b82e26cd22
Operating System: Ubuntu 20.04.6 LTS
OSType: linux
Architecture: aarch64
CPUs: 12
Total Memory: 19.5GiB
Name: dc773ac7bce3
ID: daf97268-48c1-44df-a7ce-b588fa71dcfb
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Builders list
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default* docker
\_ default \_ default running v0.12.5 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/arm/v7, linux/arm/v6
Configuration
docker-bake.json
{
"target": {
"default": {
"dockerfile": "Dockerfile",
"tags": ["webapp:latest"],
"labels": {
"foo": "%{bar}"
}
}
}
}
Build logs
$ docker buildx bake
[+] Building 0.0s (1/1) FINISHED docker:default
=> [internal] load local bake definitions 0.0s
=> => reading docker-bake.json 162B / 162B 0.0s
docker-bake.json:7
--------------------
5 | "tags": ["webapp:latest"],
6 | "labels": {
7 | >>> "foo": "%{bar}"
8 | }
9 | }
--------------------
ERROR: docker-bake.json:7,19-22: Invalid template control keyword; "bar" is not a valid template control keyword. Did you mean "for"?, and 1 other diagnostic(s)
Additional info
We use the json format of docker bake as we prefer to programmatically generate JSON instead of manually editing HCL. I expect that this would be the most common case for using JSON.
When generating JSON config programmatically, applying HCL string templates is both undesired (we would prefer to do any manipulation on the input before generating the JSON) and also dangerous (it can end up violating validations that we perform before generating the JSON file).
If the current behavior is working as intended, it should at least be documented as such, as the behavior is surprising when programmatically generating raw JSON objects.
I think there are cases where access to variables and directives would be useful from JSON format. If you want raw strings then these can be escaped with %% or $$.
It does look that atm when using --print with an escaped value we would print the "%{bar}" directly. That does not look correct as I think the output of --print should be usable as input. I think we should escape the output of --print (unless we want to make loading raw json vs JSON-with-templates configurable somehow).