--- tags: rfc --- > TODO: > - [ ] Add app developer use cases > - [ ] Upgrade > - [ ] Mixins # Extending Images UX The definition of an extended image is that of which an execution occurs within the running of a container to produce mutation to said image. ``` +-----+ | | | e | | x | | t | | e | | n | +----------------+ | s | +-----------------------+ | | | i | | | | some/image | +--> | o | +--> | some/extended-image | | | | n | | | +----------------+ | | +-----------------------+ | f | | u | | n | | c | | | +-----+ ``` Within the context of builders, it makes sense to provide this functionality to the following images: - builder image - run image _We exclude build image because the builder is based (and therefor) effectively the build image but there is no technical limitation as to why they should be excluded._ An image can be extended if it adheres to the contract defined in [RFC #TBD](https://github.com/buildpacks/rfcs/blob/app-image-ext/text/0000-app-image-extensions.md#specification). ## Operators The use cases this tries to solve are the following: * As an operator, I want to produce a builder image that has package X installed from the OS. * As an operator, I want to produce a run image that has package X installed from the OS. * As an operator, I want to add OS packages to an existing builder image. * As an operator, I want to add OS packages to an existing run image. ### `pack extend`: Extending any image ```shell pack extend <image-name> [image-name, ...] --config extend.toml ``` where `extend.toml` is: ```toml [extend] image = "<image-name>" [extend.metadata] # arbitrary metadadata understood by the image being extended ``` The resulting image will contain the following information in a label `io.buildpacks.extend.metadata`. If the label exists on the image being extended it will be merged. #### Example: Extenting run image ```shell pack extend some/extended-run gcr.io/some/extended-run --config extend.toml ``` where `extend.toml` is: ```toml [extend] image = "some/run" [extend.metadata] packages = ["imagemagick"] ``` ### `pack extend-builder`: Extending an existing builder This case is more focused to extending all images associated with a builder. This includes the builder image and run image(s). ```shell pack extend-builder \ # name of image to save as # (required) *out* <image-name> \ # configuration # (required) *in* --extension-config <extend-builder.toml> \ # name to save run image as # (required if `run` image is to be extended) *out* --run-image <image-name> \ # name to save a run image mirror as # (optional) *out* --run-image-mirror <image-name> ``` `extend-builder.toml`: ```toml [extend] image = "<image-name>" [extend.metadata] # metadata provided to `run` and `build` images [extend.metadata.run] # metadata provided only to `run` images [extend.metadata.build] # metadata provided only to `build` images ``` #### Example: Extending a builder while saving only builder image ```shell pack extend-builder some/extended-builder --extension-config extend.toml ``` where `extend.toml` is: ```toml [extend] image = "some/builder" [extend.metadata.build] packages = ["git"] ``` #### Example: Extending a builder while saving all images ```shell pack extend-builder some/extended-builder \ --run-image some/extended-run \ --run-image-mirror gcr.io/some/extended-run \ --config extend.toml ``` where `extend.toml` is: ```toml [extend] image = "some/builder" [extend.metadata.run] packages = ["imagemagick"] [extend.metadata.build] packages = ["build-essentials", "imagemagick"] ``` ### Creating an extended builder > Technically, leveraging the `pack extend` command instead of a new command could achieve the same thing without adding complexity to `create-builder`. Adds configuration section and flags as defined in [`extend-builder`](#pack-extend-builder-Extending-an-existing-builder) to `pack create-builder`. ```shell pack create-builder some/extended-builder \ --run-image some/extended-run \ --run-image-mirror gcr.io/some/extended-run \ --config builder.toml ``` `builder.toml`: ```toml [[buildpacks]] # buildpacks to include in builder [[order]] [[order.group]] # execution order of buildpacks [stack] id = "<stack-id>" run-image = "<image-name>" build-image = "<image-name>" [extend] [extend.metadata] # metadata provided to `run` and `build` images [extend.metadata.run] # metadata provided only to `run` images [extend.metadata.build] # metadata provided only to `build` images ```