Skip to content

Commit

Permalink
Heroku-24: Use the same user for the run and build images (#281)
Browse files Browse the repository at this point in the history
The upstream CNB spec recently changed to say that build and run
images `SHOULD` use a separate Linux user for each image:
https://github.com/buildpacks/rfcs/blob/main/text/0085-run-uid.md
https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#run-image

However, this causes a number of compatibility issues with existing
apps and parts of the ecosystem (see #268).

Whilst we can (and will) adjust our own buildpacks to do the right thing
(not write to `/layers/` or the app source directory at runtime), it's
going to be some time before existing apps/frameworks/... make similar
changes. In addition, the failure modes are not easy for users to debug
or solve (they will have to know that seeing access denied errors means
needing to use `chmod` to make directories group writeable in an inline
buildpack step or similar).

As such, we're deferring making this switch for now, and will revisit in the
future (either for Heroku-26, or as an opt-in feature for Heroku-24), when
the various third party language ecosystems are more ready for this.

We will still be in compliance with the spec, since it says `SHOULD` not
`MUST`.

We will also add integration testing to our own CNBs to ensure that they
operate correctly in environments that do run split build/run users.

As part of this change, I've also switched the `heroku` user's ID back to
1000, for consistency with the Heroku-20/22 CNB base images.

I've also switched back to the `USER <name>` syntax instead of `USER <id>`,
since both are permitted by the OCI and CNB specs, and the former is
(a) IMO more intuitive (eg for users needing to switch to `root` and back
in their own `Dockerfile`), (b) matches what Heroku-20/22 do.

See also:
https://manpages.ubuntu.com/manpages/noble/en/man8/userdel.8.html
https://manpages.ubuntu.com/manpages/noble/en/man8/groupadd.8.html

Closes #268.
GUS-W-15342842.
  • Loading branch information
edmorley authored Mar 27, 2024
1 parent 46b68ce commit 76c7ea9
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 12 deletions.
3 changes: 1 addition & 2 deletions heroku-20-cnb-build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ RUN groupadd heroku --gid 1000 \
&& chown heroku:heroku /app

# https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#build-image
USER heroku
ENV CNB_USER_ID=1000
ENV CNB_GROUP_ID=1000
# Note: This image doesn't inherit from the CNB run image variant so we have
Expand All @@ -20,5 +21,3 @@ LABEL io.buildpacks.base.maintainer="Heroku"
# https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#iobuildpacksstack-labels
ENV CNB_STACK_ID="heroku-20"
LABEL io.buildpacks.stack.id="heroku-20"

USER heroku
3 changes: 1 addition & 2 deletions heroku-22-cnb-build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ RUN groupadd heroku --gid 1000 \
&& chown heroku:heroku /app

# https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#build-image
USER heroku
ENV CNB_USER_ID=1000
ENV CNB_GROUP_ID=1000
# Note: This image doesn't inherit from the CNB run image variant so we have
Expand All @@ -20,5 +21,3 @@ LABEL io.buildpacks.base.maintainer="Heroku"
# https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#iobuildpacksstack-labels
ENV CNB_STACK_ID="heroku-22"
LABEL io.buildpacks.stack.id="heroku-22"

USER heroku
6 changes: 3 additions & 3 deletions heroku-24-build/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
ARG BASE_IMAGE=heroku/heroku:24
FROM $BASE_IMAGE

# We have to temporarily switch back to root, since the run image sets a non-root default USER.
# We have to temporarily switch back to root, since the run image sets a non-root default `USER`.
USER root
RUN --mount=target=/build /build/setup.sh

# https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#build-image
# The `io.buildpacks.base.*` labels are inherited from the run image, so don't need to be repeated here.
USER 1002
ENV CNB_USER_ID=1002
USER heroku
ENV CNB_USER_ID=1000
ENV CNB_GROUP_ID=1000

# Stack IDs are deprecated, but we still set this for backwards compatibility:
Expand Down
2 changes: 1 addition & 1 deletion heroku-24/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM ubuntu:24.04
RUN --mount=target=/build /build/setup.sh

# https://github.com/buildpacks/spec/blob/platform/0.13/platform.md#run-image
USER 1001
USER heroku
LABEL io.buildpacks.base.distro.name="ubuntu"
LABEL io.buildpacks.base.distro.version="24.04"
LABEL io.buildpacks.base.homepage="https://github.com/heroku/base-images"
Expand Down
10 changes: 6 additions & 4 deletions heroku-24/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,12 @@ apt-get purge -y openjdk-8-jre-headless
apt-get autoremove -y --purge
test "$(file -b /etc/ssl/certs/java/cacerts)" = "Java KeyStore"

useradd heroku --uid 1001 --gid 1000 --shell /bin/bash --create-home
useradd heroku-build --uid 1002 --gid 1000 --shell /bin/bash --create-home
groupmod --new-name heroku ubuntu
deluser --remove-home ubuntu
# Ubuntu 24.04 ships with a default user and group named 'ubuntu' (with user+group ID of 1000)
# that we have to remove before creating our own (`userdel` will remove the group too).
userdel ubuntu --remove

groupadd heroku --gid 1000
useradd heroku --uid 1000 --gid 1000 --shell /bin/bash --create-home

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

0 comments on commit 76c7ea9

Please sign in to comment.