With the aim of avoiding root user running in the container, I’ve got the following Dockerfile:
FROM public.ecr.aws/docker/library/node:14-alpine AS deps
RUN apk add --no-cache libc6-compat curl
&& addgroup --system --gid 1001 app_user
&& adduser --system --uid 1001 app_user
RUN mkdir /app
&& chown -R app_user:app_user /app
USER app_user
WORKDIR /app
COPY --chown=app_user:app_user package*.json yarn.lock ./
RUN yarn install --production=false --pure-lockfile --ignore-engines
FROM public.ecr.aws/docker/library/node:14-alpine AS builder
WORKDIR /app
COPY --chown=app_user:app_user components pages public queries styles lib @types ./
COPY --chown=app_user:app_user tsconfig.json constants.js next.config.js .babelrc ./
COPY --chown=app_user:app_user scripts/cache/ ./scripts/cache
COPY --chown=app_user:app_user --from=deps /usr/src/app/package.json ./
COPY --chown=app_user:app_user --from=deps /usr/src/app/node_modules ./node_modules
ENV CACHE_REFRESH_SECRET_TOKEN=$CACHE_REFRESH_SECRET_TOKEN
RUN CODEBUILD_BUILD_ID=$CODEBUILD_BUILD_ID DEBUG=graphql:errors,graphql:queries,cache:redis DEBUG_COLORS=true npm run build
EXPOSE 8080 6379
ENTRYPOINT [ "npm", "start"]
Line COPY --chown=app_user:app_user package*.json yarn.lock ./
won’t fail, but once reaching the line COPY --chown=app_user:app_user components pages public queries styles lib @types ./
it’ll err out with the following message:
unable to convert uid/gid chown string to host mapping: can't find uid for user app_user: no such user: app_user
I’m a bit strange as I think I’m following directions from docs and multiple guides. What should be corrected?
2
Answers
In multistage of docker build you can not re-use the same user so in each
FROM
you must re-create it.I made the changes in lines 17 to 23
There’s no particular requirement that the (non-root) user running the container be the same user that owns the files. It can be a minor security improvement to have the source code owned by root and not world-writable, which will prevent the application from doing things like overwriting its own static images (intentionally or otherwise).
One straightforward approach is to do all of the package installation and building as root in the Dockerfile, and only switch to the non-root user at the very end of the Dockerfile.