Skip to content

Support persisting changes to a stage mount #6704

@jlebon

Description

@jlebon

We'd like to be able to do something like:

FROM quay.io/fedora/fedora-minimal AS final

FROM quay.io/fedora/fedora-minimal AS build
RUN --mount=type=bind,from=build,target=/final,persist echo foobar > /final/foobar.txt

FROM final

Where changes to the stage done through its mount are persisted (i.e. committed) rather than lost as part of the throwaway overlay. (Notice the persist mount option there.)

The use case for this is when you want to use an image with some kind of build tool to operate on the final image without wanting to ship that build tool itself in the image. The buildah answer to this currently are the buildah from ... and buildah commit primitives. The proposal here is to support a Containerfile-native way to do this, which would have major UX and CI advantages.

That said, two concrete use cases to motivate this further:

  1. In Project Hummingbird, we ship distroless images (i.e. without dnf). Multi-stage builds is fine for the initial base image build. But we also want users to be able to extend our images using dnf without actually needing dnf in the image. So e.g. it would permit something like:

    FROM quay.io/hummingbird/rust:latest-builder AS builder
    COPY . /build
    WORKDIR /build
    RUN dnf install -y libfoobar-devel && cargo build --release
    
    FROM quay.io/hummingbird/core-runtime AS final
    COPY --from=builder /build/target/release/myapp /usr/local/bin/myapp
    
    # add runtime dep libfoobar to final image using dnf from builder image
    FROM quay.io/hummingbird/rust:latest-builder
    RUN --mount=type=bind,from=final,target=/final,persist dnf install -y --installroot /final ... libfoobar
    
    FROM final

    (This could be shorter, but keeping it similar to the traditional multi-stage flow for clarity.)

  2. In bootable containers, users want to be able to run their Ansible playbooks to configure their image at build time. See e.g. https://github.com/nzwulfin/bootc-django (that uses the host Ansible) and https://gitlab.com/fedora/bootc/examples/-/blob/main/ansible-firewalld/Containerfile?ref_type=heads (installs Ansible, runs it, then uninstalls it). This would become:

    FROM quay.io/centos-bootc/centos-bootc:stream10 AS final
    
    # NB: there might be a well-known user-facing ansible image that exists already
    FROM quay.io/centos/centos:stream10 AS ansible
    RUN dnf install -y ansible-core
    COPY . /src
    RUN --mount=type=bind,from=final,target=/final,persist ansible-playbook -c chroot -i /src/inventory ...
    
    FROM final

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/featureCategorizes issue or PR as related to a new feature.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions