Porter Buildtime Architecture

In Porter, “buildtime” refers to authoring and building a bundle. A bundle is defined by a manifest, porter.yaml, where you define:

  • Parameters to customize the bundle.
  • Credentials to authenticate to services and resources used by the bundle.
  • Outputs generated by the bundle.
  • Mixins used by the bundle. Mixins help you install and interact with tools in the bundle.
  • Actions such as install, upgrade or uninstall. These contain the steps to execute when that bundle action is run.

Mixins must be installed to the same machine where the bundle is built. So for example, if you want to use the kubernetes mixin in your bundle, first run porter mixins install kubernetes. Mixins are cached in your PORTER_HOME directory, and the kubernetes mixin can be found in ~/.porter/mixins/kubernetes after it is installed. Porter does not support specifying which version of a mixin to use in a bundle yet. You can follow the Mixins are Bundles proposal to keep track of that feature’s progress.

When the bundle author runs porter build, Porter first generates a Dockerfile to create an image for the bundle (known as the bundle image or installer). You can define your own custom Dockerfile to customize and optimize the image.

Porter supports two build modes, controlled by the experimental optimized-bundle-build feature flag:

Default Build Mode (Legacy)

By default, Porter builds using your bundle directory as the build context:

  • Build context: Your bundle’s root directory
  • User files: Copied with COPY . ${BUNDLE_DIR}, then porter.yaml and .cnab are removed
  • CNAB directory: Copied separately with COPY .cnab /cnab
  • Permissions: Set via RUN chgrp and chmod commands

The generated Dockerfile includes:

  • A base image (debian:stable-slim)
  • Additional customizations generated by the mixins
  • COPY statements for user files and the .cnab directory
  • RUN commands to clean up and set permissions

Optimized Build Mode (Experimental)

When you enable experimental = ["optimized-bundle-build"] in ~/.porter/config.toml, Porter uses an optimized approach:

  • Build context: The generated .cnab directory (contains Porter runtime, mixin runtimes, and canonical porter.yaml)
  • User files: Made available through a named build context called porter-internal-userfiles
  • Permissions: Set during COPY using --chown and --chmod flags
  • Result: ~54% smaller images by eliminating duplicate layers

The generated Dockerfile includes:

  • A base image (debian:stable-slim)
  • Additional customizations generated by the mixins
  • A COPY statement with --from=porter-internal-userfiles to include user files efficiently
  • A single COPY statement for .cnab contents with inline permission setting

This optimized build structure minimizes image size by avoiding duplicate layers and efficiently organizing bundle contents.

After the image is built, Porter generates a CNAB-compliant bundle.json file that defines the bundle’s metadata.

See Also