docker-node: Permissions error - after declaring USER and WORKDIR
I have this:
FROM node:9
USER node
WORKDIR /home/node/app
COPY package.json .
RUN npm install --loglevel=warn;
and I get:
Step 20/24 : RUN npm install --loglevel=warn;
---> Running in 8aa9717ac2be
npm WARN checkPermissions Missing write access to /home/node/app
npm ERR! path /home/node/app
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall access
npm ERR! Error: EACCES: permission denied, access '/home/node/app'
npm ERR! { Error: EACCES: permission denied, access '/home/node/app'
npm ERR! stack: 'Error: EACCES: permission denied, access \'/home/node/app\'',
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'access',
npm ERR! path: '/home/node/app' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/node/.npm/_logs/2018-05-16T17_37_34_421Z-debug.log
this seems completely crazytown. How does my user not have access to this directory by default considering it was “created” by the WORKDIR command after USER was declared?
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 67
- Comments: 38 (1 by maintainers)
Commits related to this issue
- fix: docker build tsc permission issue tsc fails with permission denied for writing under lib. Fixed with advice from https://github.com/nodejs/docker-node/issues/740#issuecomment-468629313 — committed to SignalK/signalk-server by tkurki 5 years ago
- create the dir ourselves https://github.com/nodejs/docker-node/issues/740#issuecomment-538644464 — committed to openwhyd/openwhyd by adrienjoly 3 years ago
- Fix permission issue on npm install This alpine version is overriding the custom user: - https://github.com/nodejs/docker-node/issues/740 - https://stackoverflow.com/questions/44766665/how-do-i-docke... — committed to allamasln/tbstore by allamasln 2 years ago
Just do this and call it a day lol
F it lol…just run that before and after
npm install
and you should be g2g. Even better, do this:This has been a nightmare for me… Can this be documented as what the Best Practice is suggesting to use
USER node
but doesn’t provide a viable config?@albertoantunes You are right, it worked for me. Here is my Dockerfile, hope it helps some with the same problem.
@ORESoftware i believe this issue happens because only the /home/node directory is owned by the node user in the default node image. The /app directory is created and owned by root. If you change the WORKDIR to /home/node it should work.
@ORESoftware I had the same issue, you can specify the user with the COPY command. See my Dockerfile:
The COPY is done by default with root (source):
Note that
COPY --chown
won’t work with all docker versions (see here). Mine is 18.03.1-ce.Correct me if I’m wrong. The doc is recommending us to declare user as node because Docker runs container as root by default.
So you declare it at the end
If I remember correctly, folder created by
WORKDIR
are owned by root even if they are created after theUSER
directive. Try creating the folder firstThis worked for me. A combination of using the existing
/home/node
dir to host the app files and specifying the user and group for theCOPY
commands.I had the same issue and here’s my Dockerfile. This fixed it
The trick was to use
@abhaykumar01234 , the basic problem is that your container is using a user (in this case
node
, I believe) which does not map (see below) onto a user in the host that has permission to write to the directory you mounted. You get an error because thenpm install
writes to that directory but the user in the host doesn’t have permission.It helps to understand what “map” means here: When a Docker container is run, the users inside the container are also interpreted as users in the host. The identity of the host user is determined by the numeric user id of the user inside the container.
All solutions to this problem involve ensuring that the user inside the container maps onto a suitable user on the host. This can be done in several ways.
The simplest way is to define and use a user in the image (i.e., in the Dockerfile) whose numeric user id is the same as a host user with suitable permissions (e.g., your own user id). This is not very flexible because the user id is fixed, but if you don’t need that flexibility, it’s effective.
A more flexible way to do much the same thing is to specify a user id externally when you build your image. There’s some good advice on this in Avoiding Permission Issues With Docker-Created Files.
A more complex but fully flexible solution to the problem is to use Docker’s user namespace mapping facility. I am doing this with a couple of Python projects, and I haven’t yet worked out all the kinks, but in principle it’s reasonably straightforward. I found the following articles helpful:
A few other remarks:
COPY
it also in the image. The mount supersedes the copy.node:latest
set for you? Is your own Dockerfile’s commandUSER node
necessary?Yeah I tried that too, I still get permissions errors with this:
You should not run node as root, bad things can happen (see the last issue with changing files permissions). I think you need to make sure that when the
node
user is created it has the right permissions over/home/node
(eg. https://github.com/vvo/selenium-standalone/blob/master/Dockerfile#L29). Maybe the permissions are not well propagated to subsequent directories:@ORESoftware do a
docker exec ls -al /home/node/app
and check who owns that?Note this comment in the Best Practices documentation:
# At the end, set the user to use when running this image
. What I ended up doing is running the Dockefile as theroot
user, then copying everything I need, using the--chown node:node
flag in theCOPY
command when needed, then changing the user tonode
before running the application.I was able to solve this with a newer docker backend component called buildkit. Buildkit mode is enabled by default for Docker Desktop users, and can be enabled manually by setting an environment variable when building the image:
DOCKER_BUILDKIT=1 docker build ...
Buildkit creates directories a little differently. Say we have a dockerfile that just prints out details of the
WORKDIR
:Without buildkit, the
WORKDIR
is owned by root:With buildkit, the
WORKDIR
is owned by ourUSER
:When the
WORKDIR
is owned by theUSER
, any furtherRUN
commands that want to create files in theWORKDIR
will have enough permissions.hi guys,
sometimes this happens - when the container you are trying to use (FROM) - set up the user already and it is different from the root. In this case permission is denied
I added ‘user: node’ on my docker-compose.yml and it fixed the issue.
Guys, I’m absolultly shit at Docker, I don’t understand anything in this thread. Can someone please help me?
Here’s my
Dockerfile
:I get this error:
Years later, you are helping me when several guides from well-known tech companies have failed. Thanks!
I know WORKDIR permissions
@herbievine , I think your problem is that
WORKDIR
creates the working directory asroot
, but the process is running as usernode
when you run theCMD
. (Pretty sure the default user for the imagenode
– your base image – is usernode
.) This means that GraphQL (or anything else) can’t create files in the working directory, which is what appears to be problem here.The likely fix is to explicitly create the
WORKDIR
directory and give it correct ownership and permissions before you select it asWORKDIR
. You may need to do this asroot
:Don’t stay as user
root
for the rest of the image, it exposes a lot of security vulnerabilities and you DO NOT want that.This dockerfile works fine with any image but the issue comes when you try to mount the volume
<current_dir>:/home/node
How to fix this? How to mount current folder as volume inside docker container?
may anyone could use it, we solved Jenkins Docker scripted pipeline build with the following setup/commands/variables:
docker.image('node:8').inside("-e npm_config_cache=$env.WORKSPACE/.npm") { sh "npm install && export BABEL_CACHE_PATH=$env.WORKSPACE/.babel.json && npm run build" }