Skip to content

Commit 10cb812

Browse files
Fix support for Heroku-24 (#15)
* try with Dockerfile * add heroku 24 * separate packages for heroku-24 * remove packages from heroku-24 these no longer exist * Test that Chrome is on PATH and can launch To make testing fully representative of the Heroku platform, we have to run the built app against the run image and not the build image. (Whilst Heroku CI will use the build image, some apps will use the buildpack outside of CI, and so against the run image which has fewer system libraries than the build image.) * Add a `.dockerignore` to speed up local iteration This prevents unnecessary Docker cache invalidation when editing files that don't affect the image, meaning quicker iteration times when developing on this buildpack locally. * Fix packages on Heroku-24 Fixes this error: ``` chrome: error while loading shared libraries: libasound.so.2: cannot open shared object file: No such file or directory ``` And also cleans up the packages list, removing some packages that either are no longer needed, or already exist in the base image. This is safe to do now that `bin/test.sh` checks for missing shared libraries. --------- Co-authored-by: Ed Morley <[email protected]>
1 parent 7e489c1 commit 10cb812

File tree

5 files changed

+81
-18
lines changed

5 files changed

+81
-18
lines changed

.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.github/
2+
bin/test.sh
3+
Dockerfile

.github/workflows/build-and-test.yml

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,10 @@ jobs:
66
test:
77
strategy:
88
matrix:
9-
stack: [heroku-20, heroku-22, heroku-24]
9+
stack_version: [20, 22, 24]
1010
runs-on: ubuntu-latest
1111

1212
steps:
1313
- uses: actions/checkout@v3
14-
15-
- name: Run Buildpack Compile
16-
run: |
17-
./bin/compile . . .
18-
env:
19-
STACK: ${{ matrix.stack }}
20-
2114
- name: Check Installation
22-
run: |
23-
# Trick the profile script into using working dir as HOME
24-
HOME="$(pwd)"
25-
# Verify profile script puts Chrome & Chromedriver on the PATH
26-
source .profile.d/chrome-for-testing.sh
27-
chrome --version
28-
chromedriver --version
15+
run: ./bin/test.sh ${{ matrix.stack_version }}

Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
ARG STACK_VERSION
2+
FROM --platform=linux/amd64 heroku/heroku:${STACK_VERSION}-build as build
3+
4+
# This ARG duplication is required since the lines before and after the 'FROM' are in different scopes.
5+
ARG STACK_VERSION
6+
ENV STACK="heroku-${STACK_VERSION}"
7+
8+
# On Heroku-24 and later the default user is not root.
9+
# Once support for Heroku-22 and older is removed, the `useradd` steps below can be removed.
10+
USER root
11+
12+
# Emulate the platform where root access is not available
13+
RUN useradd -m non-root-user
14+
USER non-root-user
15+
RUN mkdir -p /tmp/build /tmp/cache /tmp/env
16+
COPY --chown=non-root-user . /buildpack
17+
18+
# Sanitize the environment seen by the buildpack, to prevent reliance on
19+
# environment variables that won't be present when it's run by Heroku CI.
20+
RUN env -i PATH=$PATH HOME=$HOME STACK=$STACK /buildpack/bin/detect /tmp/build
21+
RUN env -i PATH=$PATH HOME=$HOME STACK=$STACK /buildpack/bin/compile /tmp/build /tmp/cache /tmp/env
22+
23+
# We must then test against the run image since that has fewer system libraries installed.
24+
FROM --platform=linux/amd64 heroku/heroku:${STACK_VERSION}
25+
USER root
26+
# Emulate the platform where root access is not available
27+
RUN useradd -m non-root-user
28+
USER non-root-user
29+
COPY --from=build --chown=non-root-user /tmp/build /app
30+
# Emulate the platform which sources all .profile.d/ scripts on app boot.
31+
RUN echo 'for f in /app/.profile.d/*; do source "${f}"; done' > /app/.profile
32+
ENV HOME=/app
33+
WORKDIR /app
34+
# We have to use a login bash shell otherwise the .profile script won't be run.
35+
CMD ["bash", "-l"]

bin/install-chrome-dependencies

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
topic "Installing Chrome dependencies"
1515

1616
# Install correct dependencies according to $STACK
17+
# The package list is validated by bin/test.sh - see its output to identify any missing libraries.
18+
# Also look here for more packages/notes https://developers.google.com/web/tools/puppeteer/troubleshooting
1719
case "${STACK}" in
18-
"heroku-20" | "heroku-22" | "heroku-24")
19-
# the package list is found by using ci:debug then running ldd $GOOGLE_CHROME_BIN | grep not
20-
# also look here for more packages/notes https://developers.google.com/web/tools/puppeteer/troubleshooting
20+
"heroku-20" | "heroku-22")
2121
PACKAGES="
2222
gconf-service
2323
libappindicator1
@@ -46,6 +46,21 @@ case "${STACK}" in
4646
fonts-liberation
4747
"
4848
;;
49+
"heroku-24")
50+
PACKAGES="
51+
fonts-liberation
52+
libasound2t64
53+
libatk-bridge2.0-0
54+
libatk1.0-0
55+
libcups2
56+
libgbm1
57+
libxcomposite1
58+
libxdamage1
59+
libxfixes3
60+
libxkbcommon0
61+
libxrandr2
62+
"
63+
;;
4964
*)
5065
error "STACK must be 'heroku-20', 'heroku-22' or 'heroku-24', not '${STACK}'."
5166
esac

bin/test.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
STACK_VERSION="${1:?'Error: The stack version number must be specified as the first argument.'}"
6+
7+
set -x
8+
9+
docker build --progress=plain --build-arg="STACK_VERSION=${STACK_VERSION}" -t heroku-buildpack-chrome-for-testing .
10+
11+
# Note: All of the container commands must be run via a login bash shell otherwise the profile.d scripts won't be run.
12+
13+
# Check the profile.d scripts correctly added the binaries to PATH.
14+
docker run heroku-buildpack-chrome-for-testing bash -l -c 'chrome --version'
15+
docker run heroku-buildpack-chrome-for-testing bash -l -c 'chromedriver --version'
16+
17+
# Check that there are no missing dynamically linked libraries.
18+
docker run heroku-buildpack-chrome-for-testing bash -l -c 'ldd $(which chrome)'
19+
docker run heroku-buildpack-chrome-for-testing bash -l -c 'ldd $(which chromedriver)'
20+
21+
# Check Chrome can fully boot in both new and old headless modes.
22+
docker run heroku-buildpack-chrome-for-testing bash -l -c 'chrome --no-sandbox --headless=new --screenshot https://google.com'
23+
docker run heroku-buildpack-chrome-for-testing bash -l -c 'chrome --no-sandbox --headless=old --screenshot https://google.com'

0 commit comments

Comments
 (0)