Skip to content

docker import, docker commit: separate --changes from Dockerfile syntax #50170

@thaJeztah

Description

@thaJeztah

Description

related:

The --change flag on docker import / docker image import and docker commit / docker container commit were implemented in #9123 after many debates (see the list of tickets / pulls above). At the time, docker commit was a core component of docker build with the classic builder, which would run a container for each step in the Dockerfile, then docker commit the result to an image for each step. Re-using the same functionality for a "manual" docker commit therefore was an easy way to expose that functionality, and to allow alternative builder implementations to create images. Similarly, adding those options to docker image import allowed for importing a rootfs, and modifying the image Config, without that requiring a Dockerfile to be created.

Ultimately, the options was a bit of a hack though; while the functionality on its own is useful, the implementatino through a single -c / --changes flag starts to show its age;

  • the use of Dockerfile syntax to apply changes to the image config makes it hard to discover what options are supported.
  • as only Config changes / metadata changes are allowed, only a subset of Dockerfile instructions can be supported (as no container is started in the process).
  • with the Dockerfile syntax itself evolving (BuildKit added options to existing commands), the syntax supported by --changes may no longer match the syntax as documented in the Dockerfile reference. This means that we either must use BuildKit's parser for Dockerfiles, but explicitly disabling options that are not supported, or to maintain a separate implementation of the Dockerfile parser to handle this flag.
  • The legacy ("classic") builder is deprecated, and in future will be removed; we also want to have a better separation between the "docker daemon" and "buildkit" - possibly even delegating build to a separate binary.

My proposal is to start looking at options to separate the --changes feature from the Dockerfile syntax.

Phase 1: through documentation

This would be an "intermediate" solution; update the documentation to not refer to the Dockerfile syntax for the --changes flags, instead, document the syntax that's accepted by the flag, and only the accepted formats.

Phase 2: alternative flag, or distinct flags

Instead of the --changes flag, we can introduce a new flag to apply config-changes to the committed (or "imported") image, for example, --set-config. This flag could accept a CSV format (as we use for, e.g. --mount) with a documented set of options;

--set-config cmd=["/bin/sh"],env=SOME_VAR=hello

Given the many different possible options, this may not be a good choice though, because many options could contain quotes and/or could take either JSON ("exec-style") or string ("command-style") values.

Alternatively, we can add dedicated flags for configuratino options that can be applied to the image, e.g.;

--entrypoint
--cmd / --command
--env
--label

These options are already available on docker create and docker run, so can take the same syntax as supported there, which helps users re-use their knowledge about those options.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/featureFunctionality or other elements that the project doesn't currently have. Features are new and shiny

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions