Skip to content

Commit

Permalink
use unprivileged user in a container
Browse files Browse the repository at this point in the history
  • Loading branch information
ajgon committed Jan 12, 2023
1 parent 88c4375 commit 03294b5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 17 deletions.
32 changes: 16 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ WORKDIR /app

COPY --link package.json pnpm-lock.yaml* ./

RUN <<EOF
set -xe
apk add libc6-compat
apk add --virtual .gyp python3 make g++
npm install -g pnpm
EOF
SHELL ["/bin/ash", "-xeo", "pipefail", "-c"]
RUN apk add --no-cache libc6-compat \
&& apk add --no-cache --virtual .gyp python3 make g++ \
&& npm install -g pnpm

RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm fetch | grep -v "cross-device link not permitted\|Falling back to copying packages from store"

Expand All @@ -29,12 +27,10 @@ ARG REVISION
COPY --link --from=deps /app/node_modules ./node_modules/
COPY . .

RUN <<EOF
set -xe
npm run telemetry
mkdir config && echo '-' > 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
Expand All @@ -50,17 +46,21 @@ 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

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"]
16 changes: 15 additions & 1 deletion docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 03294b5

Please sign in to comment.