Package: container-prefab
Build container images faster⚡️Prefabis a Python-based container image build tool that uses deterministic remote caching to reduce build times.  UnlikeBuildKitand theDocker CLI, which use build layer caching,Prefabuses whole image caching based on a digest of the Dockerfile in combination with digests of specified files and directory trees.  This allowsPrefabto check for and pull cached images before resorting to building a new image.QuickstartLook at theexample directoryto see how to build an example app withPrefab.Installation and usagePrefabcan be installed and run in three different ways:Local Python packageDocker outside of Docker (DooD) containerDocker in Docker (DinD) containerUse whichever mode works best for the use-case(s) at hand.  Each supports the same CLI arguments:CLI argumentsusage: prefab [-h] [--config PATH] [--dry-run] [--force] [--monochrome]
              [--push TARGET_NAME [TARGET_NAME ...]] [--push-all] --repo URI
              --target TARGET_NAME[:TAG] [TARGET_NAME[:TAG] ...]

Build container images faster ⚡️

optional arguments:
  -h, --help            show this help message and exit
  --config PATH, -c PATH
                        Target build config file to use (default: prefab.yml)
  --dry-run             Show how targets would be built (implies --force)
  --force               Force target(s) to be rebuilt
  --monochrome, -m      Don't colorize log messages
  --push TARGET_NAME [TARGET_NAME ...], -p TARGET_NAME [TARGET_NAME ...]
                        Image target(s) to push to repo after building
  --push-all            Push all image targets to repo after building
  --repo URI, -r URI    Image repo to use (e.g. lexsca/prefab)
  --target TARGET_NAME[:TAG] [TARGET_NAME[:TAG] ...], -t TARGET_NAME[:TAG] [TARGET_NAME[:TAG] ...]
                        Image target(s) to build with optional custom image tagLocal Python packageTo installPrefabas a local Python package:pip install container-prefabTo runPrefabas a local Python package to build an push a build target:prefab --repo repo.tld/org/project --push --target nameNOTE: Container images now hosted on Docker HubThe container images below used to be hosted by Quay and are now
hosted byDocker HubThis decision was not taken lightly. Sadly, Quay has not proven to
be a reliable service. The final straw was when RedHat acquired
them and broke authentication.Docker outside of Docker (DooD)To get thePrefabDocker outside of Docker (DooD) image:docker pull lexsca/prefab:doodTo run thePrefabDocker outside of Docker image to build an push a build target:docker run --rm -it -v $(/bin/pwd):/build -w /build \
    -e REGISTRY_AUTH=$(jq -c . ~/.docker/config.json | base64) \
    -v /var/run/docker.sock:/docker.sock \
    lexsca/prefab:dood --repo repo.tld/org/project \
    --push --target nameDocker in Docker (DinD)To get thePrefabDocker in Docker (DinD) image:docker pull lexsca/prefab:dindTo run thePrefabDocker in Docker image to build an push a build target:docker run --rm -it -v $(/bin/pwd):/build -w /build --privileged \
    -e REGISTRY_AUTH=$(jq -c . ~/.docker/config.json | base64) \
    lexsca/prefab:dind --repo repo.tld/org/project \
    --push --target nameConfigurationPrefabuses aYAMLconfiguration file to determine which container images to build for a given target and in which order.  This configuration below is taken from theexample directoryin this repo.Theprefab.ymlfile has two build targets, each with a Dockerfile. Theapptarget has a dependency on thepackagestarget, so it’s built or pulled first, before building theapptarget.  This is a simple example, but the dependency graph can be arbitrarily deep or wide for complex build targets.prefab.ymltargets:

  app:
    dockerfile: Dockerfile.app
    depends_on:
      - packages
    watch_files:
      - app.py

  packages:
    dockerfile: Dockerfile.packagesWhen building a container image,Prefabpopulatesbuild argumentsfor each build target depndency, uppercased by convention, and prefixed withPREFAB_to avoid conflicts with other build arguments.Dockerfile.appARG PREFAB_PACKAGES

FROM $PREFAB_PACKAGES as packagesContributingBug reports are welcome.  Pull requests even more so.Before making any changes, first ensure the development environment is functional and the extant linting and tests are passing.  To start a development environment, clone or fork this source repo and follow the instructions below.Alternatively, it’s fine to create a virtual environment an install packages fromrequirements.txtandrequirements-dev.txtfiles. The Python version should be 3.7 or later.PrerequisitesPOSIX Shell (e.g. bash)DockerGNU MakeCreate environmentTo create a development runtime environment:$ make bootstrapThe above will create a minimal environment that will allowPrefabto build its development environment image.  This image can be used to run linting and tests:$ docker images lexsca/prefab:dev
REPOSITORY      TAG                 IMAGE ID            CREATED              SIZE
lexsca/prefab   dev                 ddee1cafb775        About a minute ago   429MBUse environmentOnce created, the development image can used via:$ make shell
docker run --rm -it -v /Users/lexsca/git/prefab:/prefab -w /prefab \
        -v /var/run/docker.sock:/docker.sock -e PYTHONPATH=/prefab/lib \
        --entrypoint /bin/bash lexsca/prefab:dev --login -o vi
3053ae861610:/prefab# make testThis will mount the docker socket and current working directory in an environment where tests can be run, dependencies built, or a debugger invoked to aid in iterating.Themake testcommand should pass before attempting to submit any code changes.