Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into multiarch-push-robuust
Browse files Browse the repository at this point in the history
  • Loading branch information
boboldehampsink authored May 30, 2024
2 parents cf02dc1 + 3e34d02 commit 4bb290a
Show file tree
Hide file tree
Showing 16 changed files with 199 additions and 298 deletions.
36 changes: 22 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,28 @@
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 | Base | Type | Status |
|-------------------------------------------|---------------------------------------|--------------------|-------------|
| [heroku/heroku:18][heroku-tags] | [ubuntu:18.04][ubuntu-tags] | Heroku Run Image | End-of-life |
| [heroku/heroku:18-build][heroku-tags] | [heroku/heroku:18][heroku-tags] | Heroku Build Image | End-of-life |
| [heroku/heroku:18-cnb][heroku-tags] | [heroku/heroku:18][heroku-tags] | CNB Run Image | End-of-life |
| [heroku/heroku:18-cnb-build][heroku-tags] | [heroku/heroku:18-build][heroku-tags] | CNB Build Image | End-of-life |
| [heroku/heroku:20][heroku-tags] | [ubuntu:20.04][ubuntu-tags] | Heroku Run Image | Available |
| [heroku/heroku:20-build][heroku-tags] | [heroku/heroku:20][heroku-tags] | Heroku Build Image | Available |
| [heroku/heroku:20-cnb][heroku-tags] | [heroku/heroku:20][heroku-tags] | CNB Run Image | Available |
| [heroku/heroku:20-cnb-build][heroku-tags] | [heroku/heroku:20-build][heroku-tags] | CNB Build Image | Available |
| [heroku/heroku:22][heroku-tags] | [ubuntu:22.04][ubuntu-tags] | Heroku Run Image | Recommended |
| [heroku/heroku:22-build][heroku-tags] | [heroku/heroku:22][heroku-tags] | Heroku Build Image | Recommended |
| [heroku/heroku:22-cnb][heroku-tags] | [heroku/heroku:22][heroku-tags] | CNB Run Image | Recommended |
| [heroku/heroku:22-cnb-build][heroku-tags] | [heroku/heroku:22-build][heroku-tags] | CNB Build Image | Recommended |
| 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 |

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.

The CNB image variants contain additional metadata and changes required to make them compatible with
Heroku's Cloud Native Buildpacks [builder images](https://github.com/heroku/cnb-builder-images).

For images where the default `USER` is `heroku`, you will need to switch back to the `root` user when
modifying locations other then `/home/heroku` and `/tmp`. You can do this by adding `USER root` to
your `Dockerfile` when building images, or by passing `--user root` to any `docker run` invocations.

### Learn more

Expand Down
36 changes: 20 additions & 16 deletions bin/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ write_package_list() {
output_file="${dockerfile_dir}/installed-packages-${arch}.txt"
display "Generating package list: ${output_file}"
echo "# List of packages present in the final image. Regenerate using bin/build.sh" > "$output_file"
docker run --rm --platform="linux/${arch}" "$image_tag" dpkg-query --show --showformat='${Package}\n' >> "$output_file"
# We include the package status in the output so we can differentiate between fully installed
# packages, and those that have been removed but not purged (either because we forgot to purge,
# or because we intentionally left config files behind, such as for `ca-certificates-java`).
docker run --rm --platform="linux/${arch}" "$image_tag" dpkg-query --show --showformat='${Package} (package status: ${db:Status-Status})\n' \
| sed -e 's/ (package status: installed)//' >> "$output_file"
done
}

Expand All @@ -121,21 +125,21 @@ display "Building ${RUN_DOCKERFILE_DIR} / ${RUN_IMAGE_TAG} image"
# from upstream ubuntu images are included.
docker "${DOCKER_ARGS[@]}" --pull \
--tag "${RUN_IMAGE_TAG}" "${RUN_DOCKERFILE_DIR}" | indent
write_package_list "${RUN_IMAGE_TAG}" "${RUN_DOCKERFILE_DIR}"

for VARIANT in "${VARIANTS[@]}"; do
VARIANT_NAME=$(echo "$VARIANT" | cut -d ":" -f 1)
DEPENDENCY_NAME=$(echo "$VARIANT" | cut -d ":" -f 2)
VARIANT_IMAGE_TAG="${REPO}:${STACK_VERSION}${VARIANT_NAME}${PUBLISH_SUFFIX}"
VARIANT_DOCKERFILE_DIR="heroku-${STACK_VERSION}${VARIANT_NAME}"
DEPENDENCY_IMAGE_TAG="${REPO}:${STACK_VERSION}${DEPENDENCY_NAME}${PUBLISH_SUFFIX}"

[[ -d "${VARIANT_DOCKERFILE_DIR}" ]] || abort "fatal: directory ${VARIANT_DOCKERFILE_DIR} not found"
display "Building ${VARIANT_DOCKERFILE_DIR} / ${VARIANT_IMAGE_TAG} image"
# The --pull option is not used for variants since they depend on images
# built earlier in this script.
docker "${DOCKER_ARGS[@]}" --build-arg "BASE_IMAGE=${DEPENDENCY_IMAGE_TAG}" \
--tag "${VARIANT_IMAGE_TAG}" "${VARIANT_DOCKERFILE_DIR}" | indent
write_package_list "${RUN_IMAGE_TAG}" "${RUN_DOCKERFILE_DIR}"

for VARIANT in "${VARIANTS[@]}"; do
VARIANT_NAME=$(echo "$VARIANT" | cut -d ":" -f 1)
DEPENDENCY_NAME=$(echo "$VARIANT" | cut -d ":" -f 2)
VARIANT_IMAGE_TAG="${REPO}:${STACK_VERSION}${VARIANT_NAME}${PUBLISH_SUFFIX}"
VARIANT_DOCKERFILE_DIR="heroku-${STACK_VERSION}${VARIANT_NAME}"
DEPENDENCY_IMAGE_TAG="${REPO}:${STACK_VERSION}${DEPENDENCY_NAME}${PUBLISH_SUFFIX}"

[[ -d "${VARIANT_DOCKERFILE_DIR}" ]] || abort "fatal: directory ${VARIANT_DOCKERFILE_DIR} not found"
display "Building ${VARIANT_DOCKERFILE_DIR} / ${VARIANT_IMAGE_TAG} image"
# The --pull option is not used for variants since they depend on images
# built earlier in this script.
docker "${DOCKER_ARGS[@]}" --build-arg "BASE_IMAGE=${DEPENDENCY_IMAGE_TAG}" \
--tag "${VARIANT_IMAGE_TAG}" "${VARIANT_DOCKERFILE_DIR}" | indent

# generate the package list for non-cnb variants. cnb variants don't
# influence the list of installed packages.
Expand Down
4 changes: 3 additions & 1 deletion heroku-20-build/installed-packages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ build-essential
bzip2
bzr
ca-certificates
ca-certificates-java
ca-certificates-java (package status: config-files)
clang-10
cmake
cmake-data
Expand Down Expand Up @@ -127,6 +127,7 @@ libbsd-dev
libbsd0
libbz2-1.0
libbz2-dev
libc-ares2
libc-bin
libc-client2007e
libc-client2007e-dev
Expand Down Expand Up @@ -542,6 +543,7 @@ mlock
mount
mtools
mysql-common
nano
ncurses-base
ncurses-bin
netbase
Expand Down
1 change: 0 additions & 1 deletion heroku-20-build/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ packages=(
cmake
gettext
git
jq
libacl1-dev
libapt-pkg-dev
libargon2-dev
Expand Down
6 changes: 5 additions & 1 deletion heroku-20/installed-packages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ binutils-x86-64-linux-gnu
bsdutils
bzip2
ca-certificates
ca-certificates-java
ca-certificates-java (package status: config-files)
coreutils
cpp
cpp-9
Expand Down Expand Up @@ -69,6 +69,7 @@ imagemagick-6.q16
init-system-helpers
iproute2
iputils-tracepath
jq
language-pack-en
language-pack-en-base
less
Expand All @@ -93,6 +94,7 @@ libblkid1
libbrotli1
libbsd0
libbz2-1.0
libc-ares2
libc-bin
libc-client2007e
libc-dev-bin
Expand Down Expand Up @@ -186,6 +188,7 @@ libjbig0
libjbig2dec0
libjpeg-turbo8
libjpeg8
libjq1
libjson-c4
libk5crypto3
libkeyutils1
Expand Down Expand Up @@ -339,6 +342,7 @@ mlock
mount
mtools
mysql-common
nano
ncurses-base
ncurses-bin
netbase
Expand Down
24 changes: 16 additions & 8 deletions heroku-20/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ packages=(
imagemagick
iproute2
iputils-tracepath
jq # Used by Heroku Exec at run time, and buildpacks at build time.
language-pack-en
less
libaom0
libargon2-1
libass9
libc-ares2 # Used by PgBouncer in heroku-buildpack-pgbouncer.
libc-client2007e
libc6-dev
libcairo2
Expand Down Expand Up @@ -130,6 +132,7 @@ packages=(
locales
lsb-release
make
nano # More usable than ed but still much smaller than vim.
netcat-openbsd
openssh-client
openssh-server
Expand Down Expand Up @@ -160,16 +163,21 @@ apt-get install -y --no-install-recommends "${packages[@]}"

cp /build/imagemagick-policy.xml /etc/ImageMagick-6/policy.xml

# Temporarily install ca-certificates-java to generate the certificates store used
# by Java apps. Generation occurs in a post-install script which requires a JRE.
# We're using OpenJDK 8 rather than something newer, to work around:
# https://github.com/heroku/base-images/pull/103#issuecomment-389544431
# Install ca-certificates-java so that the JVM buildpacks can configure Java apps to use the Java certs
# store in the base image instead of the one that ships in each JRE release, allowing certs to be updated
# via base image updates. Generation of the `cacerts` file occurs in a post-install script which requires
# a JRE, however, we don't want a JRE in the final image so remove it afterwards.
apt-get install -y --no-install-recommends ca-certificates-java openjdk-8-jre-headless
# Using remove rather than purge so that the generated certs are left behind.
# For Ubuntu versions prior to 24.04 the ca-certificates-java package has a direct dependency on a JRE, so
# we can't remove the JRE without also removing ca-certificates-java. However, we can work around this by
# not using `--purge` when removing ca-certificates-java, which leaves behind the generated certs store.
apt-get remove -y ca-certificates-java
apt-get purge -y openjdk-8-jre-headless
apt-get autoremove -y --purge
test "$(file -b /etc/ssl/certs/java/cacerts)" = "Java KeyStore"
apt-get remove -y --purge --auto-remove openjdk-8-jre-headless
# Check that the certs store (a) wasn't purged during removal of ca-certificates-java, (b) uses the JKS
# format not PKCS12, since in the past there was an upstream regression for this:
# https://github.com/heroku/base-images/pull/103#issuecomment-389544431
# https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/1771363
test "$(file --brief /etc/ssl/certs/java/cacerts)" = "Java KeyStore"

rm -rf /root/*
rm -rf /tmp/*
Expand Down
4 changes: 3 additions & 1 deletion heroku-22-build/installed-packages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ build-essential
bzip2
bzr
ca-certificates
ca-certificates-java
ca-certificates-java (package status: config-files)
cmake
cmake-data
comerr-dev
Expand Down Expand Up @@ -127,6 +127,7 @@ libbsd-dev
libbsd0
libbz2-1.0
libbz2-dev
libc-ares2
libc-bin
libc-client2007e
libc-client2007e-dev
Expand Down Expand Up @@ -541,6 +542,7 @@ mlock
mount
mtools
mysql-common
nano
ncurses-base
ncurses-bin
netbase
Expand Down
1 change: 0 additions & 1 deletion heroku-22-build/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ packages=(
cmake
gettext
git
jq
libacl1-dev
libapt-pkg-dev
libargon2-dev
Expand Down
6 changes: 5 additions & 1 deletion heroku-22/installed-packages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ binutils-x86-64-linux-gnu
bsdutils
bzip2
ca-certificates
ca-certificates-java
ca-certificates-java (package status: config-files)
coreutils
cpp
cpp-11
Expand Down Expand Up @@ -68,6 +68,7 @@ imagemagick-6.q16
init-system-helpers
iproute2
iputils-tracepath
jq
language-pack-en
language-pack-en-base
less
Expand All @@ -93,6 +94,7 @@ libbpf0
libbrotli1
libbsd0
libbz2-1.0
libc-ares2
libc-bin
libc-client2007e
libc-dev-bin
Expand Down Expand Up @@ -187,6 +189,7 @@ libjbig0
libjbig2dec0
libjpeg-turbo8
libjpeg8
libjq1
libjson-c5
libk5crypto3
libkeyutils1
Expand Down Expand Up @@ -344,6 +347,7 @@ mlock
mount
mtools
mysql-common
nano
ncurses-base
ncurses-bin
netbase
Expand Down
24 changes: 16 additions & 8 deletions heroku-22/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ packages=(
imagemagick
iproute2
iputils-tracepath
jq # Used by Heroku Exec at run time, and buildpacks at build time.
language-pack-en
less
libaom3
libargon2-1
libass9
libc-ares2 # Used by PgBouncer in heroku-buildpack-pgbouncer.
libc-client2007e
libc6-dev
libcairo2
Expand Down Expand Up @@ -133,6 +135,7 @@ packages=(
locales
lsb-release
make
nano # More usable than ed but still much smaller than vim.
netcat-openbsd
openssh-client
openssh-server
Expand Down Expand Up @@ -162,16 +165,21 @@ apt-get install -y --no-install-recommends "${packages[@]}"

cp /build/imagemagick-policy.xml /etc/ImageMagick-6/policy.xml

# Temporarily install ca-certificates-java to generate the certificates store used
# by Java apps. Generation occurs in a post-install script which requires a JRE.
# We're using OpenJDK 8 rather than something newer, to work around:
# https://github.com/heroku/base-images/pull/103#issuecomment-389544431
# Install ca-certificates-java so that the JVM buildpacks can configure Java apps to use the Java certs
# store in the base image instead of the one that ships in each JRE release, allowing certs to be updated
# via base image updates. Generation of the `cacerts` file occurs in a post-install script which requires
# a JRE, however, we don't want a JRE in the final image so remove it afterwards.
apt-get install -y --no-install-recommends ca-certificates-java openjdk-8-jre-headless
# Using remove rather than purge so that the generated certs are left behind.
# For Ubuntu versions prior to 24.04 the ca-certificates-java package has a direct dependency on a JRE, so
# we can't remove the JRE without also removing ca-certificates-java. However, we can work around this by
# not using `--purge` when removing ca-certificates-java, which leaves behind the generated certs store.
apt-get remove -y ca-certificates-java
apt-get purge -y openjdk-8-jre-headless
apt-get autoremove -y --purge
test "$(file -b /etc/ssl/certs/java/cacerts)" = "Java KeyStore"
apt-get remove -y --purge --auto-remove openjdk-8-jre-headless
# Check that the certs store (a) wasn't purged during removal of ca-certificates-java, (b) uses the JKS
# format not PKCS12, since in the past there was an upstream regression for this:
# https://github.com/heroku/base-images/pull/103#issuecomment-389544431
# https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/1771363
test "$(file --brief /etc/ssl/certs/java/cacerts)" = "Java KeyStore"

rm -rf /root/*
rm -rf /tmp/*
Expand Down
Loading

0 comments on commit 4bb290a

Please sign in to comment.