`imagetools create` with single source changes copied image from `application/vnd.docker.distribution.manifest.v2+json` to `application/vnd.docker.distribution.manifest.list.v2+json`
rvoh-tismith opened this issue · comments
Contributing guidelines
- I've read the contributing guidelines and wholeheartedly agree
I've found a bug and checked that ...
- ... the documentation does not mention anything about my problem
- ... there are no open or closed issues that are related to my problem
Description
Based on documentation from https://docs.docker.com/reference/cli/docker/buildx/imagetools/create/ that says:
The source manifests can be manifest lists or single platform distribution manifests and must already exist in the registry where the new manifest is created. If only one source is specified, create performs a carbon copy.
I would expect that running imagetools create
against one source with a mediaType of application/vnd.docker.distribution.manifest.v2+json
and a configType of application/vnd.docker.container.image.v1+json
to produce a "carbon copy" that has the same mediaType and configType, however instead I end up with a copy that is now a manifest list, or in other words, it now has a mediaType of application/vnd.docker.distribution.manifest.list.v2+json
.
Expected behaviour
We have an image at (made-up registry and repo obviously) foo/bar:oldimage
with the following manifest (shrunk for readability):
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"digest": "...",
"size": 3060
},
"layers": [...]
}
I would expect that running the command docker buildx imagetools create -t foo/bar:newimage foo/bar:oldimage
, which has a single source that is a single platform distribution manifest, would create a new image at foo/bar:newimage
with a manifest that basically looks the same as the above with the same mediaType
and configType
.
Actual behaviour
Instead, the image at foo/bar:newimage
is now a manifest list and looks more like:
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "...",
"size": 1687,
"platform": {
"architecture": "arm64",
"os": "linux"
}
}
]
}
Buildx version
github.com/docker/buildx v0.14.0-52-g55c86543 55c8654
Docker info
Client:
Version: 26.1.1
Context: desktop-linux
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.14.0-52-g55c86543
Path: /Users/.../.docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.27.0-desktop.2
Path: /Users/.../.docker/cli-plugins/docker-compose
debug: Get a shell into any image or container (Docker Inc.)
Version: 0.0.29
Path: /Users/.../.docker/cli-plugins/docker-debug
dev: Docker Dev Environments (Docker Inc.)
Version: v0.1.2
Path: /Users/.../.docker/cli-plugins/docker-dev
extension: Manages Docker extensions (Docker Inc.)
Version: v0.2.23
Path: /Users/.../.docker/cli-plugins/docker-extension
feedback: Provide feedback, right in your terminal! (Docker Inc.)
Version: v1.0.4
Path: /Users/.../.docker/cli-plugins/docker-feedback
init: Creates Docker-related starter files for your project (Docker Inc.)
Version: v1.1.0
Path: /Users/.../.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/.../.docker/cli-plugins/docker-sbom
scout: Docker Scout (Docker Inc.)
Version: v1.8.0
Path: /Users/.../.docker/cli-plugins/docker-scout
Server:
Containers: 26
Running: 1
Paused: 0
Stopped: 25
Images: 54
Server Version: 26.1.1
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: runc io.containerd.runc.v2
Default Runtime: runc
Init Binary: docker-init
containerd version: e377cd56a71523140ca6ae87e30244719194a521
runc version: v1.1.12-0-g51d5e94
init version: de40ad0
Security Options:
seccomp
Profile: unconfined
cgroupns
Kernel Version: 6.6.26-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: aarch64
CPUs: 12
Total Memory: 7.657GiB
Name: docker-desktop
ID: 951123a4-fb43-48fc-b36c-20354178644c
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/.../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
Builders list
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
magical_dijkstra* docker-container
\_ magical_dijkstra0 \_ desktop-linux running v0.12.4 linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
default docker
\_ default \_ default running v0.13.2 linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
desktop-linux docker
\_ desktop-linux \_ desktop-linux running v0.13.2 linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
Configuration
Minimal Dockerfile (tried with a couple of other base image like alpine
, etc. that all behaved the same way)
FROM golang:latest
CMD echo "hello, world"
Command I ran (with fake registry/repo)
docker buildx imagetools create -t foo/bar:newimage foo/bar:oldimage`
Build logs
No response
Additional info
Now, I'm partially calling this a bug and partially asking if maybe I just don't understand the intention behind this if it isn't a bug, because when you run docker buildx build ...
and only specify one platform (or no platform), you get an image with a manifest just like the one shown above for foo/bar:oldimage
-- in other words, you basically get a single platform distribution manifest instead of a manifest list. So, based on that behavior AND based on the documentation I mentioned above it definitely seems like I should be getting a copy at foo/bar:newimage
that is a single platform distribution manifest, not a manifest list.
I did go ahead and open a PR to "fix" this, assuming it actually ends up being a bug and not intended behavior I don't yet understand (#2482). However I'll obviously close that out if it turns out this isn't a bug at all.
For clarity, I'll point out that some good conversation is happening over on the PR (#2482).
Closing as this was fixed in #2482!