From 03294b5a2f7a32a24c4ad03bec39c00d5cef53ad Mon Sep 17 00:00:00 2001 From: Igor Rzegocki Date: Thu, 8 Dec 2022 20:37:45 +0100 Subject: [PATCH] use unprivileged user in a container --- Dockerfile | 32 ++++++++++++++++---------------- docker-entrypoint.sh | 16 +++++++++++++++- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/Dockerfile b/Dockerfile index 48e5d2f30..1d9a49317 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,12 +7,10 @@ WORKDIR /app COPY --link package.json pnpm-lock.yaml* ./ -RUN < config/settings.yaml - NEXT_PUBLIC_BUILDTIME=$BUILDTIME NEXT_PUBLIC_VERSION=$VERSION NEXT_PUBLIC_REVISION=$REVISION npm run build -EOF +SHELL ["/bin/ash", "-xeo", "pipefail", "-c"] +RUN npm run telemetry \ + && mkdir config && echo '---' > config/settings.yaml \ + && NEXT_PUBLIC_BUILDTIME=$BUILDTIME NEXT_PUBLIC_VERSION=$VERSION NEXT_PUBLIC_REVISION=$REVISION npm run build # Production image, copy all the files and run next FROM docker.io/node:18-alpine AS runner @@ -50,12 +46,15 @@ ENV NODE_ENV production WORKDIR /app # Copy files from context (this allows the files to copy before the builder stage is done). -COPY --link package.json next.config.js ./ -COPY --link /public ./public +COPY --link --chown=1000:1000 package.json next.config.js ./ +COPY --link --chown=1000:1000 /public ./public/ # Copy files from builder -COPY --link --from=builder /app/.next/standalone ./ -COPY --link --from=builder /app/.next/static/ ./.next/static/ +COPY --link --from=builder --chown=1000:1000 /app/.next/standalone ./ +COPY --link --from=builder --chown=1000:1000 /app/.next/static/ ./.next/static/ +COPY --link --chmod=755 docker-entrypoint.sh /usr/local/bin/ + +RUN apk add --no-cache su-exec ENV PORT 3000 EXPOSE $PORT @@ -63,4 +62,5 @@ EXPOSE $PORT HEALTHCHECK --interval=10s --timeout=3s --start-period=20s \ CMD wget --no-verbose --tries=1 --spider --no-check-certificate http://localhost:$PORT/api/healthcheck || exit 1 +ENTRYPOINT ["docker-entrypoint.sh"] CMD ["node", "server.js"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 5603d7e58..bf443461f 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -2,8 +2,22 @@ set -e +# Default to root, so old installations won't break +export PUID=${PUID:-0} +export PGID=${PGID:-0} + # This is in attempt to preserve the original behavior of the Dockerfile, # while also supporting the lscr.io /config directory [ ! -d "/app/config" ] && ln -s /config /app/config -node server.js +# Set privileges for /app but only if pid 1 user is root and we are dropping privileges. +# If container is run as an unprivileged user, it means owner already handled ownership setup on their own. +# Running chown in that case (as non-root) will cause error +[ "$(id -u)" == "0" ] && [ "${PUID}" != "0" ] && chown -R ${PUID}:${PGID} /app + +# Drop privileges (when asked to) if root, otherwise run as current user +if [ "$(id -u)" == "0" ] && [ "${PUID}" != "0" ]; then + su-exec ${PUID}:${PGID} "$@" +else + exec "$@" +fi