Mansur Ali Koroglu
Mansur Ali Koroglu

Reputation: 1918

node in docker container is unable to use node_modules folder

I have a dockerfile like this:

FROM node:alpine

WORKDIR /app

COPY package.json .

RUN npm install

VOLUME [ "/app/node_modules" ]

COPY . .

ENTRYPOINT [ "npm" ]
CMD [ "run", "dev" ]

I build my image by using the command below:

docker build -t my-vue-app .

Then I run my container by using the command below:

docker run -v $(pwd):/app --name app -it --rm my-vue-app

It outputs a permission error:

error when starting dev server:
Error: EACCES: permission denied, mkdir '/app/node_modules/.vite'
    at Object.mkdirSync (node:fs:1024:3)
    at optimizeDeps (/app/node_modules/vite/dist/node/chunks/dep-efe32886.js:65416:21)
    at runOptimize (/app/node_modules/vite/dist/node/chunks/dep-efe32886.js:69180:54)
    at Server.httpServer.listen (/app/node_modules/vite/dist/node/chunks/dep-efe32886.js:69194:23)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)

I override my entrypoint to access my container's file system to check permissions.

docker run -v $(pwd):/app --name app -it --rm --entrypoint /bin/sh my-vue-app

/app # ls -l | grep node_modules

I can see the owner and group of node_modules is root

Output:

drwxr-xr-x   52 root     root          4096 Mar 18 20:04 node_modules

All the other files have owner and group node

/app # ls -l
total 28
-rw-rw-r--    1 node     node           154 Mar 18 20:02 Dockerfile
-rw-r--r--    1 node     node           337 Mar 18 19:26 index.html
drwxr-xr-x   52 root     root          4096 Mar 18 20:04 node_modules
-rw-r--r--    1 node     node           307 Mar 18 19:26 package.json
drwxr-xr-x    2 node     node          4096 Mar 18 19:26 public
drwxr-xr-x    4 node     node          4096 Mar 18 19:26 src
-rw-r--r--    1 node     node           156 Mar 18 19:26 vite.config.js

So, I wonder why does it happen and what can I do to solve it? Also one thing is, when I use node:lts instead of node:alpine, user and group of node_modules is still root but it works fine.

Currently node:lts is node:14.16.0.

Upvotes: 1

Views: 4078

Answers (1)

David Maze
David Maze

Reputation: 158908

You should remove all mention of volumes of any sort in this entire setup. Do not declare a VOLUME for the node_modules directory; do not replace the image's code using a docker run -v option.

Once you do this, the image will be self-contained. You can push it to a registry if you'd like, and docker run it on another system without separately downloading the code. Bind-mounts can cause host user IDs and build-time user IDs to get confused, which is likely what's happening in your setup. The VOLUME will also cause Docker to leak anonymous volumes, and in a Compose-based setup will likely cause any changes in your package.json file to get ignored.

This approach won't support live reloading inside a container, but it's very easy to install Node on the host (and you may have it already), and a host-based Node will work much better with IDEs and other tooling.

(I would also combine the ENTRYPOINT and CMD into a single CMD. If nothing else, this will simplify the "run a debugging shell" case by not requiring the docker run --entrypoint option; you can docker run --rm -it my-vue-app /bin/sh.)

Upvotes: 2

Related Questions