From 998eb9344538f5e85a556033d031402f3bc0dc4d Mon Sep 17 00:00:00 2001 From: Ker Fern Tan Date: Wed, 5 Aug 2026 21:57:16 +1000 Subject: [PATCH] Run the Gradle build as a non-root user The builder stage ran Gradle as root, so Log4jMigrationsTest's read-only file assertion failed - root ignores POSIX permission bits. Building the Dockerfile from scratch therefore either failed on that test or had to skip the test suite entirely. Drop to the ubuntu user (uid 1000) that the base image already ships - the same account the runner stages rename to engine. Signed-off-by: Ker Fern Tan --- Dockerfile | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4ed4782cd3..5790ae52cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,20 +16,31 @@ SHELL ["/bin/bash", "-c"] ARG GRADLE_BUILD_ARGS="-PdisableSigning=true" # Stage 1a: Install dependencies -# Install necessary tools -COPY .sdkmanrc . +# Install necessary tools, then drop root. The base image ships a +# pre-created "ubuntu" user (uid 1000, the same one the runner stage +# below renames to "engine") — reuse it so Gradle doesn't run as root, +# which ignores POSIX permission bits and breaks tests that depend on +# them (e.g. Log4jMigrationsTest's read-only-file assertion). RUN apt-get update\ && apt-get install -y zip curl\ - && curl -s "https://get.sdkman.io?ci=true" | bash \ - && source "$HOME/.sdkman/bin/sdkman-init.sh" && sdk env install \ - && rm -rf /var/lib/apt/lists/* + && rm -rf /var/lib/apt/lists/* \ + && chown ubuntu:ubuntu /app +USER ubuntu + +COPY --chown=ubuntu:ubuntu .sdkmanrc . +RUN curl -s "https://get.sdkman.io?ci=true" | bash \ + && source "$HOME/.sdkman/bin/sdkman-init.sh" && sdk env install # Stage 1b: Build the application # Copy the entire source tree (excluding .dockerignore files), and build # (file encoding is pinned to UTF-8 in gradle.properties) -COPY . . -RUN --mount=type=cache,target=/root/.gradle/caches,sharing=locked \ - --mount=type=cache,target=/root/.gradle/wrapper,sharing=locked \ +COPY --chown=ubuntu:ubuntu . . +# The cache mounts below own their own target dirs (uid/gid), but not the +# ~/.gradle parent itself — Gradle also writes ~/.gradle/native (extracted +# native-platform lib) outside either mount, so create the parent up front. +RUN mkdir -p /home/ubuntu/.gradle +RUN --mount=type=cache,target=/home/ubuntu/.gradle/caches,sharing=locked,uid=1000,gid=1000 \ + --mount=type=cache,target=/home/ubuntu/.gradle/wrapper,sharing=locked,uid=1000,gid=1000 \ source "$HOME/.sdkman/bin/sdkman-init.sh" \ && ./gradlew --no-daemon build ${GRADLE_BUILD_ARGS}