(EACCES: permission denied, mkdir '/usr/app/node_modules/.cache) How can I create a docker-compose file to make node_modules a non-root folder?
I'm trying to dockerize a simple create-react-app project. (Is the initial project after running npx create-react-app test
, no files were changed).
The problem seems to be that in newer versions of React, they moved the annoying .eslintcache
from the root folder to /node_modules/.cache
, causing problems when the container is trying to run the application via docker-compose
.
Dockerfile
FROM node:alpine
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
RUN chown -R node.node /usr/app/node_modules
COPY . ./
CMD ["npm", "start"]
docker-compose
version: '3'
services:
test:
stdin_open: true
build:
context: .
dockerfile: Dockerfile
environment:
- CHOKIDAR_USEPOLLING=true
volumes:
- /usr/app/node_modules
- .:/usr/app
ports:
- '3000:3000'
The container is logging this error message:
test_1 | Failed to compile.
test_1 |
test_1 | EACCES: permission denied, mkdir '/usr/app/node_modules/.cache
As you can notice, I tried to set the node_modules
folder owner to the node user (the default user for node:alpine
), but it is not working; exploring the container, you can see that the node_modules
folder is still owned by root
:
drwxrwxr-x 5 node node 4096 Apr 14 07:04 .
drwxr-xr-x 1 root root 4096 Apr 14 07:08 ..
-rw-rw-r-- 1 node node 310 Apr 14 06:56 .gitignore
-rw-rw-r-- 1 node node 192 Apr 14 07:30 Dockerfile
-rw-rw-r-- 1 node node 3369 Apr 14 06:56 README.md
drwxrwxr-x 1061 root root 36864 Apr 14 07:12 node_modules
-rw-rw-r-- 1 node node 692936 Apr 14 06:56 package-lock.json
-rw-rw-r-- 1 node node 808 Apr 14 06:56 package.json
drwxrwxr-x 2 node node 4096 Apr 14 06:56 public
drwxrwxr-x 2 node node 4096 Apr 14 06:56 src
I also tried to create the folder RUN mkdir -p /usr/app
and use USER node
but that end up in an issue where npm wasn't able to create the node_modules
folder.
Is there any workaround where either .eslintcache
is disabled or node_modules
is owned by the node
user?
Update
Apparently, this is occurring because I'm using Ubuntu and docker mounts volumes as root on Linux systems.
Solution 1:
Adding this line just after RUN npm install
in your Dockerfile would solve the issue:
RUN mkdir -p node_modules/.cache && chmod -R 777 node_modules/.cache
Final Dockerfile
FROM node:alpine
WORKDIR /usr/app
COPY package.json .
RUN npm install
RUN mkdir node_modules/.cache && chmod -R 777 node_modules/.cache
COPY . .
CMD ["npm", "run", "start"]
Then you don't need to copy the node_modules
folder from your local dir to the container. You can safely bookmark it.
Solution 2:
I've just stumbled across the same issue. If you're wondering how I dealt with it I simply added two lines before the last line. It worked like a charm.
FROM node:16.13.0-alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
RUN npm config set unsafe-perm true
RUN npm install --silent
COPY . .
RUN chown -R node /app/node_modules
USER node
CMD ["npm", "start"]