1

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.

1 Answer 1

2

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.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.