dockerdocker-composechown

Docker EACCES permission denied mkdir


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


Solution

  • 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