| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
Ran every --change instruction through both nerdctl (this branch, built in a Linux/containerd sandbox) and Docker 29.4.0 with identical inputs. All supported instructions — inspect .Config is identical. $ nerdctl import \
--change 'CMD ["echo","hi"]' --change 'ENTRYPOINT ["/bin/sh","-c"]' \
--change 'ENV FOO=bar BAZ=qux' --change 'ENV SINGLE hello world' \
--change 'LABEL role=demo tier="two words"' --change 'EXPOSE 8080 53/udp' \
--change 'USER nobody:nogroup' --change 'VOLUME ["/data","/cache"]' \
--change 'WORKDIR /srv' rootfs.tar combimg
$ nerdctl image inspect combimg --format '{{json .Config}}'
{"User":"nobody:nogroup","AttachStdin":false,"ExposedPorts":{"53/udp":{},"8080/tcp":{}},"Env":["FOO=bar","BAZ=qux","SINGLE=hello world"],"Cmd":["echo","hi"],"Image":"docker.io/library/combimg:latest","Volumes":{"/cache":{},"/data":{}},"WorkingDir":"/srv","Entrypoint":["/bin/sh","-c"],"Labels":{"role":"demo","tier":"two words"}}
Docker, same command: $ docker image inspect combimg --format '{{json .Config}}'
{"User":"nobody:nogroup","ExposedPorts":{"53/udp":{},"8080/tcp":{}},"Env":["FOO=bar","BAZ=qux","SINGLE=hello world"],"Entrypoint":["/bin/sh","-c"],"Cmd":["echo","hi"],"Volumes":{"/cache":{},"/data":{}},"WorkingDir":"/srv","Labels":{"role":"demo","tier":"two words"}}
Same User, both ENV forms (k=v pairs and the legacy key value), the quoted LABEL value, EXPOSE port/proto, VOLUME, WORKDIR, CMD, ENTRYPOINT. (nerdctl's dockercompat output carries a couple of harmless extra keys such as Image/AttachStdin; the config values themselves match.) Shell-form CMD/ENTRYPOINT — both wrap in /bin/sh -c. $ nerdctl import --change 'CMD echo hi there' --change 'ENTRYPOINT /entrypoint.sh --flag' rootfs.tar shellimg
$ nerdctl image inspect shellimg --format '{{json .Config}}'
{"AttachStdin":false,"Cmd":["/bin/sh","-c","echo hi there"],"Image":"docker.io/library/shellimg:latest","Entrypoint":["/bin/sh","-c","/entrypoint.sh --flag"]}
$ docker image inspect shellimg --format '{{json .Config}}'
{"Entrypoint":["/bin/sh","-c","/entrypoint.sh --flag"],"Cmd":["/bin/sh","-c","echo hi there"]}
Instructions not representable in the OCI image config — nerdctl rejects them: $ nerdctl import --change 'HEALTHCHECK CMD true' rootfs.tar x FATA[0000] invalid --change "HEALTHCHECK CMD true": the HEALTHCHECK instruction is not supported by import $ nerdctl import --change 'ONBUILD RUN true' rootfs.tar x FATA[0000] invalid --change "ONBUILD RUN true": the ONBUILD instruction is not supported by import $ nerdctl import --change 'SHELL ["/bin/bash","-c"]' rootfs.tar x FATA[0000] invalid --change "SHELL [\"/bin/bash\",\"-c\"]": the SHELL instruction is not supported by import $ nerdctl import --change 'RUN echo x' rootfs.tar x FATA[0000] invalid --change "RUN echo x": unknown instruction "RUN" Docker rejects SHELL and RUN too (SHELL/RUN is not a valid change command). It differs only on HEALTHCHECK and ONBUILD, which it accepts because its own image-config schema carries those fields — the OCI config that import writes has no place for them, so nerdctl rejects rather than silently dropping. |
Sorry, something went wrong.
Apply Dockerfile-style instructions to the config of the image created by `nerdctl import`, matching `docker import --change`. Supported instructions are the ones representable in the OCI image config: CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, USER, VOLUME, WORKDIR, STOPSIGNAL. HEALTHCHECK, ONBUILD and SHELL only exist in Docker's config schema and are rejected with a clear error. --change applies to a filesystem (rootfs) import, which builds a fresh config; it is rejected for a standard image archive that already carries its own config. Part of containerd#3867 Signed-off-by: Mayur Das <mayur.das@neevcloud.com>
There was a problem hiding this comment.
Can we invoke buildctl build ?
Sorry, something went wrong.
There was a problem hiding this comment.
Tried it.
The Dockerfile has to be FROM <the image we just imported>, which only resolves on a containerd-worker buildkitd in the same namespace and snapshotter and import needs no daemon today.
Worse, BuildKit runs everything we pass it:
$ nerdctl import --change 'RUN touch /pwned' rootfs.tar img docker.io/library/img:latest $ nerdctl run --rm --entrypoint /bin/ls img -la /pwned -rw-r--r-- 1 0 0 0 Sep 23 09:20 /pwned
FROM alpine is accepted too and replaces the rootfs, so we'd still need an allow-list here. It also injects a default PATH and adds a layer for WORKDIR.
Using BuildKit's Dockerfile parser in-process instead gives the same config with no daemon, and the type switch is the allow-list. moby/buildkit is already in the module graph. Would that work for you?
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
docker import --change applies Dockerfile instructions to the config of the image it creates; nerdctl had it listed as unimplemented (part of #3867). This implements it.
nerdctl import --change 'CMD ["echo"]' --change 'ENV FOO=bar' rootfs.tar img now behaves like Docker. Supported instructions are the ones representable in the OCI image config that import writes: CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, USER, VOLUME, WORKDIR, STOPSIGNAL. HEALTHCHECK, ONBUILD and SHELL only exist in Docker's own image-config schema, not the OCI one, so they're rejected with a clear error instead of being silently dropped.
--change only makes sense when building a fresh config, so it applies to a filesystem (rootfs) import and is rejected for a standard image archive that already carries its own config.
Checked against Docker 29.4.0 in a Linux/containerd sandbox — inspect .Config comes out identical for the supported instructions:
$ nerdctl import --change 'CMD ["echo","hi"]' --change 'ENTRYPOINT ["/bin/sh","-c"]' \ --change 'ENV FOO=bar BAZ=qux' --change 'LABEL role=demo' --change 'WORKDIR /srv' \ --change 'EXPOSE 8080 53/udp' --change 'USER nobody' --change 'VOLUME ["/data"]' \ rootfs.tar changeimg $ nerdctl image inspect changeimg --format '{{json .Config}}' {"User":"nobody","ExposedPorts":{"53/udp":{},"8080/tcp":{}},"Env":["FOO=bar","BAZ=qux"],"Cmd":["echo","hi"],"Volumes":{"/data":{}},"WorkingDir":"/srv","Entrypoint":["/bin/sh","-c"],"Labels":{"role":"demo"}}docker gives the same config for those inputs. The unsupported ones error clearly:
The parser has unit tests per instruction (JSON vs shell form, quoted ENV/LABEL values, and the error paths) plus an integration test that imports with --change and checks the resulting config.