3

My friend gave me a project with a dockerfile which seems to work just fine for him but I get a permission error.

FROM node:alpine

RUN mkdir -p /usr/src/node-app && chown -R node:node /usr/src/node-app

WORKDIR /usr/src/node-app

COPY package.json yarn.lock ./
COPY ./api/package.json ./api/
COPY ./iso/package.json  ./iso/

USER node
RUN yarn install --pure-lockfile

COPY --chown=node:node . .

EXPOSE 3000

error An unexpected error occurred: "EACCES: permission denied, mkdir '/usr/src/node-app/node_modules/<project_name>/api/node_modules'".

Could it be a docker version error?

enter image description here

azium
  • 20,056
  • 7
  • 57
  • 79
  • My guess is that when you run the container, you map a host directory to /usr/src or /usr/src/node-app in the container. The `node` user in the container has UID 1000 and GID 1000. You need to make sure that a user with those ids can write to the directory on your host. Your friend has done that and that's why it works for him. – Hans Kilian Feb 17 '22 at 18:52

1 Answers1

7

COPY normally copies things into the image owned by root, and it will create directories inside the image if they don't exist. In particular, when you COPY ./api/package.json ./api/, it creates the api subdirectory owned by root, and when you later try to run yarn install, it can't create the node_modules subdirectory because you've switched users.

I'd recommend copying files into the container and running the build process as root. Don't chown anything; leave all of these files owned by root. Switch to an alternate USER only at the very end of the Dockerfile, where you declare the CMD. This means that the non-root user running the container won't be able to modify the code or libraries in the container, intentionally or otherwise, which is a generally good security practice.

FROM node:alpine

# Don't RUN mkdir; WORKDIR creates the directory if it doesn't exist

WORKDIR /usr/src/node-app

# All of these files and directories are owned by root
COPY package.json yarn.lock ./
COPY ./api/package.json ./api/
COPY ./iso/package.json  ./iso/
# Run this installation command still as root
RUN yarn install --pure-lockfile

# Copy in the rest of the application, still as root
COPY . .
# RUN yarn build

# Declare how to run the container -- _now_ switch to a non-root user
EXPOSE 3000
USER node
CMD yarn start
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • 1
    Is not it dangerous to do `npm ci` and `npm run build` as root for our container? what if one of our 3rd party packages be a malware (Disclaimer: I am not sure if this is even possible)? – Kasir Barati Nov 15 '22 at 04:07