adrianhajdin/docker-course

PERMISSION DENINED for vite.config.ts.timesctamp file

Opened this issue · 5 comments

When I'm trying to run my react-docker project with the command:
docker run -p 5173:5173 -v "$(pwd):/app" -v /app/node_modules react-docker

I get the following error:

failed to load config from /app/vite.config.ts
error when starting dev server:
Error: EACCES: permission denied, open '/app/vite.config.ts.timestamp-1714417454967-90458ac465121.mjs'

I have Docker Desktop installed on Windows 11 but I have my project react-docker on a linux (Debian) intance of WSL2. I have all the same settings that this repository has for the react-docker project.

I have the same issue in fedora 40. Have you figured out anything ?

Having the same problem. I also have Docker Desktop installed on Windows 11 and have my project react-docker on a Debian 12 distro in WSL2

> react-docker@0.0.0 dev
> vite --host

failed to load config from /app/vite.config.ts
error when starting dev server:
Error: EACCES: permission denied, open '/app/vite.config.ts.timestamp-1715421478918-49e8c16c2a682.mjs'
    at async open (node:internal/fs/promises:636:25)
    at async Object.writeFile (node:internal/fs/promises:1216:14)
    at async loadConfigFromBundledFile (file:///app/node_modules/vite/dist/node/chunks/dep-cNe07EU9.js:68703:9)
    at async loadConfigFromFile (file:///app/node_modules/vite/dist/node/chunks/dep-cNe07EU9.js:68558:28)
    at async resolveConfig (file:///app/node_modules/vite/dist/node/chunks/dep-cNe07EU9.js:68161:28)
    at async _createServer (file:///app/node_modules/vite/dist/node/chunks/dep-cNe07EU9.js:64686:20)
    at async CAC.<anonymous> (file:///app/node_modules/vite/dist/node/cli.js:762:24)

UPDATE:
I found a workaround for this problem by commenting out "USER app" on line 34 in the Dockerfile. Doing this basically means that our app is running with root permission (which is clearly not ideal).

If someone finds a better solution to this, please comment below

I seem to have found a solution without having the app running with root permission. The problem happens because the UID and GID of my WSL2 user is different that the UID and GID of the user app within the container. To see the differences, in WSL2 terminal, use the command id, mine outputs the following:
uid=1000(johndoe) gid=1000(johndoe) groups=1000(johndoe)

Now run the react-docker image WITHOUT mounting the host volume using docker run -p 5173:5173 react-docker. With the container running, use the Docker Desktop GUI, navigate to the Containers tab, click on the running container, navigate to Exec, and run the command id in the container's terminal. You should see that the UID and the GID of the user "app" in the container does not match the UID and GID of "johndoe" in the host system.

In my case, I ran this command in the container's terminal for user in $(cat /etc/passwd | cut -f1 -d":"); do id $user; done to list all available users and their groups. For some reason, the user "node" in the container already has UID and GID of 1000, so I ended up using "node" as my user in the Dockerfile.

Below is the Dockerfile that allowed me to successfully execute docker run -p 5173:5173 -v "$(pwd):/app" -v /app/node_modules react-docker

FROM node:20-alpine

# create a user with permissions to run the app
# -S -> create a system user
# -G -> add the user to a group
# This is done to avoid running the app as root
# If the app is run as root, any vulnerability in the app can be exploited to gain access to the host system
# It's a good practice to run the app as a non-root user
# RUN addgroup app && adduser -S -G app app

# set the user to run the app (using node because its uid and gid is 1000, which matches the host uid and gid)
USER node

# set the working directory to /app
WORKDIR /app

# copy package.json and package-lock.json to the working directory
# This is done before copying the rest of the files to take advantage of Docker’s cache
# If the package.json and package-lock.json files haven’t changed, Docker will use the cached dependencies
COPY package*.json ./

# sometimes the ownership of the files in the working directory is changed to root
# and thus the app can't access the files and throws an error -> EACCES: permission denied
# to avoid this, change the ownership of the files to the root user
USER root

# change the ownership of the /app directory to the app user
# chown -R <user>:<group> <directory>
# chown command changes the user and/or group ownership of for given file.
RUN chown -R node:node .

# change the user back to the app user
USER node

# install dependencies
RUN npm install

# copy the rest of the files to the working directory
COPY . .

# expose port 5173 to tell Docker that the container listens on the specified network ports at runtime
EXPOSE 5173

# command to run the app
CMD npm run dev```

it does not work

The problem is that the Node image creates the user "node" by default so when the user "app" and group "app" are created in this tutorial, a different UID and GUID are assigned to the user and group than the default UID=1000 and GID=1000. You can verify this by going into the terminal of the container and using the id command:

docker run -p <host_port>:<container_port> <image_name> Note that the container is run without a volume.
docker exec -it <ID for running container> sh
id

Then compare it to the the UID and GID for your user on the host machine.

This becomes a problem when you use a volume where the UID and GID needs to be the same for the user of the host machine and the user in the Docker container. The solution to this problem is either to set the user as root in the Dockerfile (bad practise) or to make sure that the UID and GUID of the host system user and Docker container user matches. If the UID=1000 and GID=1000 on your host machine user, you can just use the Node user. Then you can copy the Dockerfile of @thanhliemtu .

If the UID and GID of your host machine user is something else than 1000, you can either update the UID and GID of the node user or create an "app" user (or whatever you want to call it) and use the --uid and --gid flags.