buildah icon indicating copy to clipboard operation
buildah copied to clipboard

Allow `buildah build` to use an existing working container

Open PhrozenByte opened this issue 1 year ago • 7 comments

/kind feature

Description

Add an option to buildah build to apply instructions from Containerfiles to an existing Buildah working container. The option could be used like buildah build --use CONTAINER, where CONTAINER is the name of a Buildah working container previously created by buildah from. When a pre-existing working container is used, buildah build shouldn't commit the working container when all instructions were applied.

For single-stage Containerfiles this will cause Buildah to ignore the first and only FROM statement in the Containerfile, and rather use the existing working container instead of creating a new one. Unless the working container isn't modified before and after buildah build, this is virtually the same as buildah build --from (i.e. the new container="$(buildah from fedora)"; buildah build --use "$container"; buildah commit "$container" is the same as buildah build --from fedora). However, it gives the user the freedom to modify the working container both before, and after buildah build; it even allows one to run multiple buildah build after another, without the overhead of additional layers in between.

For multi-stage Containerfiles this new option will cause Buildah to use the existing working container as replacement for the last FROM statement in the Containerfile.

Reasoning

I often use the Containerfile of a project's official image to build my own image. The reason is that I don't want to fiddle around with build and runtime dependencies. I usually trust the project's expertise on these things...

However, I still want to do things in certain ways across a bigger variety of projects. This requires me to not only add some instructions, but to use a custom parent image. Since I don't want to manually merge all upstream changes I try to take the project's Containerfile as-is. Therefore I often build an intermediate image with buildah build --from my_base_image, and then build the final image with this intermediate image as a basis.

This works - most of the time - but has some major disadvantages: First, the buildah build --from approach doesn't work for multi-stage builds, because buildah build --from only overwrites the first FROM statement, not the last. However, the last stage is usually the one that matters: previous stages are often just builder stages. Second, buildah build always commits the container, requiring one to add another layer for additional instructions. The only way to prevent this is to append a second Containerfile to buildah build; however, Containerfiles are inflexible, I prefer using buildah mount, buildah run, et. al.

PhrozenByte avatar May 27 '23 23:05 PhrozenByte

@PhrozenByte: The label(s) kind/enhancement cannot be applied, because the repository doesn't have them.

In response to this:

/kind enhancement

Description

Add an option to buildah build to apply instructions from Containerfiles to an existing Buildah working container. The option could be used like buildah build --use CONTAINER, where CONTAINER is the name of a Buildah working container previously created by buildah from. When a pre-existing working container is used, buildah build shouldn't commit the working container when all instructions were applied.

For single-stage Containerfiles this will cause Buildah to ignore the first and only FROM statement in the Containerfile, and rather use the existing working container instead of creating a new one. Unless the working container isn't modified before and after buildah build, this is virtually the same as buildah build --from (i.e. the new container="$(buildah from fedora)"; buildah build --use "$container"; buildah commit "$container" is the same as buildah build --from fedora). However, it gives the user the freedom to modify the working container both before, and after buildah build; it even allows one to run multiple buildah build after another, without the overhead of additional layers in between.

For multi-stage Containerfiles this new option will cause Buildah to use the existing working container as replacement for the last FROM statement in the Containerfile.

Reasoning

I often use the Containerfile of a project's official image to build my own image. The reason is that I don't want to fiddle around with build and runtime dependencies. I usually trust the project's expertise on these things...

However, I still want to do things in certain ways across a bigger variety of projects. This requires me to not only add some instructions, but to use a custom parent image. Since I don't want to manually merge all upstream changes I try to take the project's Containerfile as-is. Therefore I often build an intermediate image with buildah build --from my_base_image, and then build the final image with this intermediate image as a basis.

This works - most of the time - but has some major disadvantages: First, the buildah build --from approach doesn't work for multi-stage builds, because buildah build --from only overwrites the first FROM statement, not the last. However, the last stage is usually the one that matters: previous stages are often just builder stages. Second, buildah build always commits the container, requiring one to add another layer for additional instructions. The only way to prevent this is to append a second Containerfile to buildah build; however, Containerfiles are inflexible, I prefer using buildah mount, buildah run, et. al.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

openshift-ci[bot] avatar May 27 '23 23:05 openshift-ci[bot]

/kind feature

A miss is as good as a mile...

PhrozenByte avatar May 27 '23 23:05 PhrozenByte

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Jun 27 '23 00:06 github-actions[bot]

@nalind @vrothberg @flouthoc WDYT?

rhatdan avatar Jun 27 '23 21:06 rhatdan

@PhrozenByte

Instead changing the behavior of buildah build , I'd like to propose extending/fixing buildah build --from or adding another similar command which covers the drawbacks of buildah build --from

How about if we can add a new option to buildah build --from-target which will swap the base image for target or last stage in a multi-stage build. Regarding the commit problem i did not get the issue completely if buildah manages the commits, you can use the final built image, what is the issue there ?

flouthoc avatar Jun 28 '23 04:06 flouthoc

The important bit of the suggestion is to allow buildah build to not require committing layers, neither before (i.e. buildah build (or a new command) should accept a container instead of an image as starting point), nor after (i.e. no auto commit after finishing the build) applying a Containerfile. I want to decide myself when to commit.

The reason is that after committing the layer created by buildah build, it gets immutable. Sure, you can add another layer (using buildah from or another buildah build) and overwrite or whiteout files in the next layer, but you can't change the layer created by buildah build. For example, the official PHP image includes the full (compressed) sources in the image. I can't remove this file from the image created by buildah build, I can only whiteout it in the next image resp. layer, but the space utilized remains the same.

The reasoning is more or less the same as why buildah build doesn't commit a new layer for each RUN step in a Containerfile (in contrast to Docker), but only once at the end of the Containerfile. I'd like to reduce the number of auto commits even more.

PhrozenByte avatar Jun 28 '23 10:06 PhrozenByte

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Jul 29 '23 00:07 github-actions[bot]