fix(docker): Resolve liburing.so.2 loading error for non-root users

Container failed to start when running as non-root (user 1000:1000) because
copied directories had restrictive 770 permissions, likely due to different
umask in persistent BuildKit. Non-root users couldn't access /usr/lib to
load required dynamic libraries.

Introduces prepper stage using Ubuntu to organize files into layered structure
with explicit 755 directory permissions before copying to scratch image.
Also fixes workflow syntax error and removes docker/** from paths-ignore to
ensure Docker changes trigger CI builds.
This commit is contained in:
Tom Foster 2025-09-07 13:21:58 +01:00
commit fff9629b0f
2 changed files with 42 additions and 19 deletions

View file

@ -11,7 +11,6 @@ on:
- ".gitignore" - ".gitignore"
- "renovate.json" - "renovate.json"
- "pkg/**" - "pkg/**"
- "docker/**"
- "docs/**" - "docs/**"
push: push:
branches: branches:
@ -23,7 +22,6 @@ on:
- ".gitignore" - ".gitignore"
- "renovate.json" - "renovate.json"
- "pkg/**" - "pkg/**"
- "docker/**"
- "docs/**" - "docs/**"
# Allows you to run this workflow manually from the Actions tab # Allows you to run this workflow manually from the Actions tab
workflow_dispatch: workflow_dispatch:
@ -199,7 +197,7 @@ jobs:
context: . context: .
file: "docker/Dockerfile" file: "docker/Dockerfile"
build-args: | build-args: |
GIT_COMMIT_HASH=${{ github.sha }}) GIT_COMMIT_HASH=${{ github.sha }}
GIT_COMMIT_HASH_SHORT=${{ env.COMMIT_SHORT_SHA }} GIT_COMMIT_HASH_SHORT=${{ env.COMMIT_SHORT_SHA }}
GIT_REMOTE_URL=${{github.event.repository.html_url }} GIT_REMOTE_URL=${{github.event.repository.html_url }}
GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }} GIT_REMOTE_COMMIT_URL=${{github.event.head_commit.url }}

View file

@ -199,32 +199,57 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \
EOF EOF
# Extract dynamically linked dependencies # Extract dynamically linked dependencies
RUN <<EOF RUN <<'DEPS_EOF'
set -o xtrace set -o xtrace
mkdir /out/libs mkdir /out/libs /out/libs-root
mkdir /out/libs-root
# Process each binary
for BINARY in /out/sbin/*; do for BINARY in /out/sbin/*; do
lddtree "$BINARY" | awk '{print $(NF-0) " " $1}' | sort -u -k 1,1 | awk '{print "install", "-D", $1, (($2 ~ /^\//) ? "/out/libs-root" $2 : "/out/libs/" $2)}' | xargs -I {} sh -c {} if lddtree_output=$(lddtree "$BINARY" 2>/dev/null) && [ -n "$lddtree_output" ]; then
echo "$lddtree_output" | awk '{print $(NF-0) " " $1}' | sort -u -k 1,1 | \
awk '{dest = ($2 ~ /^\//) ? "/out/libs-root" $2 : "/out/libs/" $2; print "install -D " $1 " " dest}' | \
while read cmd; do eval "$cmd"; done
fi
done done
EOF
# Show what will be copied to runtime
echo "=== Libraries being copied to runtime image:"
find /out/libs* -type f 2>/dev/null | sort || echo "No libraries found"
DEPS_EOF
FROM ubuntu:latest AS prepper
# Create layer structure
RUN mkdir -p /layer1/etc/ssl/certs \
/layer2/usr/lib \
/layer3/sbin /layer3/sbom
# Copy SSL certs and root-path libraries to layer1 (ultra-stable)
COPY --from=base /etc/ssl/certs /layer1/etc/ssl/certs
COPY --from=builder /out/libs-root/ /layer1/
# Copy application libraries to layer2 (semi-stable)
COPY --from=builder /out/libs/ /layer2/usr/lib/
# Copy binaries and SBOM to layer3 (volatile)
COPY --from=builder /out/sbin/ /layer3/sbin/
COPY --from=builder /out/sbom/ /layer3/sbom/
# Fix permissions after copying
RUN chmod -R 755 /layer1 /layer2 /layer3
FROM scratch FROM scratch
WORKDIR / WORKDIR /
# Copy root certs for tls into image # Copy ultra-stable layer (SSL certs, system libraries)
# You can also mount the certs from the host COPY --from=prepper /layer1/ /
# --volume /etc/ssl/certs:/etc/ssl/certs:ro
COPY --from=base /etc/ssl/certs /etc/ssl/certs
# Copy our build # Copy semi-stable layer (application libraries)
COPY --from=builder /out/sbin/ /sbin/ COPY --from=prepper /layer2/ /
# Copy SBOM
COPY --from=builder /out/sbom/ /sbom/
# Copy dynamic libraries to root # Copy volatile layer (binaries, SBOM)
COPY --from=builder /out/libs-root/ / COPY --from=prepper /layer3/ /
COPY --from=builder /out/libs/ /usr/lib/
# Inform linker where to find libraries # Inform linker where to find libraries
ENV LD_LIBRARY_PATH=/usr/lib ENV LD_LIBRARY_PATH=/usr/lib