diff --git a/BUILD.md b/BUILD.md index 86cc02e0..9aedf6df 100644 --- a/BUILD.md +++ b/BUILD.md @@ -2,57 +2,64 @@ ## Prepare your local environment -The build scripts in this repository require bash 4+. To update to newer bash on OS X, see: -https://johndjameson.com/blog/updating-your-shell-with-homebrew/ +The build scripts in this repository require: -## Adding packages to the base image +- bash 4+. To update to newer bash on OS X, see: https://johndjameson.com/blog/updating-your-shell-with-homebrew/ +- Docker Desktop. To build multi-arch images (heroku-24 and beyond), + the `containerd` snapshotter feature should be enabled. -Add the package you want to the appropriate `setup.sh` for example `heroku-22/setup.sh`: +## Build -```diff -+ libc6-dev \ -``` +To build the base images locally, run this from the repo root: -Once done, run the `bin/build.sh` locally to generate the corresponding `installed-packages.txt`. + bin/build.sh STACK_VERSION -The `*-build` variants include all the packages from the non-build variant by default. This means that if you're adding a package to both, you only need to add them to the non-build variant. The example above will add `libc6-dev` to both `heroku-22` and `heroku-22-build`. +For example: -The `*cnb*` variants inherit the installed packages from the non-`*cnb*` variant. Add packages to a non-`*cnb*` variant to add them to the `*cnb*` variant. + ./bin/build.sh 24 -## Build +### Multi-architecture images (heroku-24 and later) -To build the base images locally, run this from the repo root: +This script will build a family of 2 images: - bin/build.sh STACK_VERSION +* `heroku/heroku:{STACK_VERSION}` - A multi-architecture manifest list of Heroku base runtime images supporting `amd64` and `arm64` architectures +* `heroku/heroku:{STACK_VERSION}-build` - A multi-architecture manifest list of Heroku base build images supporting `amd64` and `arm64` architectures -For example: +### Single architecture images (heroku-22 and prior) + +This script will build a family of 4 images: + +* `heroku/heroku:{STACK_VERSION}` - The Heroku base run image supporting `amd64` architecture +* `heroku/heroku:{STACK_VERSION}-build` - The Heroku base build image supporting `amd64` architecture +* `heroku/heroku:{STACK_VERSION}-cnb` - The Heroku base run image for Cloud Native Buildpacks supporting `amd64` architecture +* `heroku/heroku:{STACK_VERSION}-cnb-build` - The Heroku base build image for Cloud Native Buildpacks supporting `amd64` architecture - ./bin/build.sh 22 +## Adding packages to the base image + +Add the package you want to the appropriate `setup.sh` for example `heroku-24/setup.sh`: -If you're building on a machine with an architecture other than amd64, set `DOCKER_DEFAULT_PLATFORM` to the appropriate "`linux/amd64`" value in the environment: +```diff ++ libc6-dev +``` - DOCKER_DEFAULT_PLATFORM=linux/amd64 ./bin/build.sh 22 +Once done, run `bin/build.sh` locally to generate the corresponding `installed-packages*` files. Multi-arch base images (heroku-24 and beyond) will produce an `installed-packages-$ARCH.txt` for each architecture, while single architecture images will produce a singular `installed-packages.txt`. -The supported stacks are: `20` and `22`. This script will build a family -of 4 images: +The `*-build` variants include all the packages from the non-build variant by default. This means that if you're adding a package to both, you only need to add them to the non-build variant. The example above will add `libc6-dev` to both `heroku-24` and `heroku-24-build`. -* `heroku/heroku:{STACK_VERSION}` - The base run image for the Heroku platform -* `heroku/heroku:{STACK_VERSION}-build` - The base build image for the Heroku platform -* `heroku/heroku:{STACK_VERSION}-cnb` - The base run image for Cloud Native Buildpacks -* `heroku/heroku:{STACK_VERSION}-cnb-build` - The base build image for Cloud Native Buildpacks +The `*cnb*` variants (which only exist for heroku-22 and prior) inherit the installed packages from the non-`*cnb*` variant. Add packages to a non-`*cnb*` variant to add them to the `*cnb*` variant. # Releasing Heroku Base Images We use GitHub Actions to build and release Heroku Base Images: -* Any push to `main` will build the images and push the nightly Docker tag variants (such as `heroku/heroku:22-build.nightly`). -* Any new Git tag will build the image and push the latest Docker tag (such as `heroku/heroku:22-build`), - as well as a versioned tag (such as `heroku/heroku:22-build.v123`). The Docker image will then also be +* Any push to `main` will build the images and push the nightly Docker tag variants (such as `heroku/heroku:24-build.nightly`). +* Any new Git tag will build the image and push the latest Docker tag (such as `heroku/heroku:24-build`), + as well as a versioned tag (such as `heroku/heroku:24-build.v123`). The `arm64` images will then also be converted to a Heroku-specific `.img` format and uploaded to S3 for consumption by the runtime hosts. # Generating `.img` format Base Images locally -To test the generation of the Heroku-specific `.img` file: +To test the generation of the Heroku-specific, amd64-only `.img` file: 1. Build the Docker images for your chosen stack as normal above. 2. `docker build --platform=linux/amd64 ./tools -t heroku-image-tools` diff --git a/README.md b/README.md index 14ab9f1d..8024c9cd 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,18 @@ This repository holds recipes for building the base images for [Heroku stacks](https://devcenter.heroku.com/articles/stack). The recipes are also rendered into Docker images that are available on Docker Hub: -| Image | Type | OS | Supported Architectures | Default `USER` | Status | -|-------------------------------------------|------------------------|--------------|-------------------------|----------------| ----------------| -| [heroku/heroku:20][heroku-tags] | Heroku Run Image | Ubuntu 20.04 | AMD64 | `root` | Available | -| [heroku/heroku:20-build][heroku-tags] | Heroku Build Image | Ubuntu 20.04 | AMD64 | `root` | Available | -| [heroku/heroku:20-cnb][heroku-tags] | CNB Run Image | Ubuntu 20.04 | AMD64 | `heroku` | Available | -| [heroku/heroku:20-cnb-build][heroku-tags] | CNB Build Image | Ubuntu 20.04 | AMD64 | `heroku` | Available | -| [heroku/heroku:22][heroku-tags] | Heroku Run Image | Ubuntu 22.04 | AMD64 | `root` | Recommended | -| [heroku/heroku:22-build][heroku-tags] | Heroku Build Image | Ubuntu 22.04 | AMD64 | `root` | Recommended | -| [heroku/heroku:22-cnb][heroku-tags] | CNB Run Image | Ubuntu 22.04 | AMD64 | `heroku` | Available | -| [heroku/heroku:22-cnb-build][heroku-tags] | CNB Build Image | Ubuntu 22.04 | AMD64 | `heroku` | Available | -| [heroku/heroku:24][heroku-tags] | Heroku/CNB Run Image | Ubuntu 24.04 | AMD64 + ARM64 | `heroku` | In Development | -| [heroku/heroku:24-build][heroku-tags] | Heroku/CNB Build Image | Ubuntu 24.04 | AMD64 + ARM64 | `heroku` | In Development | +| Image | Type | OS | Supported Architectures | Default `USER` | Status | +|-------------------------------------------|------------------------|--------------|-------------------------|----------------| -------------| +| [heroku/heroku:20][heroku-tags] | Heroku Run Image | Ubuntu 20.04 | AMD64 | `root` | Deprecated | +| [heroku/heroku:20-build][heroku-tags] | Heroku Build Image | Ubuntu 20.04 | AMD64 | `root` | Deprecated | +| [heroku/heroku:20-cnb][heroku-tags] | CNB Run Image | Ubuntu 20.04 | AMD64 | `heroku` | Deprecated | +| [heroku/heroku:20-cnb-build][heroku-tags] | CNB Build Image | Ubuntu 20.04 | AMD64 | `heroku` | Deprecated | +| [heroku/heroku:22][heroku-tags] | Heroku Run Image | Ubuntu 22.04 | AMD64 | `root` | Available | +| [heroku/heroku:22-build][heroku-tags] | Heroku Build Image | Ubuntu 22.04 | AMD64 | `root` | Available | +| [heroku/heroku:22-cnb][heroku-tags] | CNB Run Image | Ubuntu 22.04 | AMD64 | `heroku` | Available | +| [heroku/heroku:22-cnb-build][heroku-tags] | CNB Build Image | Ubuntu 22.04 | AMD64 | `heroku` | Available | +| [heroku/heroku:24][heroku-tags] | Heroku/CNB Run Image | Ubuntu 24.04 | AMD64 + ARM64 | `heroku` | Recommended | +| [heroku/heroku:24-build][heroku-tags] | Heroku/CNB Build Image | Ubuntu 24.04 | AMD64 + ARM64 | `heroku` | Recommended | The build image variants use the run images as their base, but include additional packages needed at build time such as development headers and compilation toolchains. diff --git a/heroku-20-cnb-build/Dockerfile b/heroku-20-cnb-build/Dockerfile index c5a62f7c..6f29af34 100644 --- a/heroku-20-cnb-build/Dockerfile +++ b/heroku-20-cnb-build/Dockerfile @@ -1,10 +1,7 @@ ARG BASE_IMAGE=heroku/heroku:20-build FROM $BASE_IMAGE -RUN groupadd heroku --gid 1000 \ - && useradd heroku --uid 1000 --gid 1000 --shell /bin/bash --create-home \ - && mkdir /app \ - && chown heroku:heroku /app +RUN mkdir /app && chown heroku:heroku /app # https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#build-image USER heroku diff --git a/heroku-20-cnb/Dockerfile b/heroku-20-cnb/Dockerfile index 1e829420..a4718690 100644 --- a/heroku-20-cnb/Dockerfile +++ b/heroku-20-cnb/Dockerfile @@ -1,9 +1,7 @@ ARG BASE_IMAGE=heroku/heroku:20 FROM $BASE_IMAGE -RUN groupadd heroku --gid 1000 \ - && useradd heroku --uid 1000 --gid 1000 --shell /bin/bash --create-home \ - && ln -s /workspace /app +RUN ln -s /workspace /app # https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#run-image USER heroku diff --git a/heroku-20/setup.sh b/heroku-20/setup.sh index cdfd1240..58e65857 100755 --- a/heroku-20/setup.sh +++ b/heroku-20/setup.sh @@ -179,6 +179,9 @@ apt-get remove -y --purge --auto-remove openjdk-8-jre-headless # https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/1771363 test "$(file --brief /etc/ssl/certs/java/cacerts)" = "Java KeyStore" +groupadd heroku --gid 1000 +useradd heroku --uid 1000 --gid 1000 --shell /bin/bash --create-home + rm -rf /root/* rm -rf /tmp/* rm -rf /var/cache/apt/archives/*.deb diff --git a/heroku-22-cnb-build/Dockerfile b/heroku-22-cnb-build/Dockerfile index b1c018ac..3dca30db 100644 --- a/heroku-22-cnb-build/Dockerfile +++ b/heroku-22-cnb-build/Dockerfile @@ -1,10 +1,7 @@ ARG BASE_IMAGE=heroku/heroku:22-build FROM $BASE_IMAGE -RUN groupadd heroku --gid 1000 \ - && useradd heroku --uid 1000 --gid 1000 --shell /bin/bash --create-home \ - && mkdir /app \ - && chown heroku:heroku /app +RUN mkdir /app && chown heroku:heroku /app # https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#build-image USER heroku diff --git a/heroku-22-cnb/Dockerfile b/heroku-22-cnb/Dockerfile index 0eda9154..599185e9 100644 --- a/heroku-22-cnb/Dockerfile +++ b/heroku-22-cnb/Dockerfile @@ -1,9 +1,7 @@ ARG BASE_IMAGE=heroku/heroku:22 FROM $BASE_IMAGE -RUN groupadd heroku --gid 1000 \ - && useradd heroku --uid 1000 --gid 1000 --shell /bin/bash --create-home \ - && ln -s /workspace /app +RUN ln -s /workspace /app # https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#run-image USER heroku diff --git a/heroku-22/setup.sh b/heroku-22/setup.sh index 3f84891e..8650837d 100755 --- a/heroku-22/setup.sh +++ b/heroku-22/setup.sh @@ -181,6 +181,9 @@ apt-get remove -y --purge --auto-remove openjdk-8-jre-headless # https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/1771363 test "$(file --brief /etc/ssl/certs/java/cacerts)" = "Java KeyStore" +groupadd heroku --gid 1000 +useradd heroku --uid 1000 --gid 1000 --shell /bin/bash --create-home + rm -rf /root/* rm -rf /tmp/* rm -rf /var/cache/apt/archives/*.deb