I’m trying to build a docker image for a simple nodeJS app but docker is not able to perform the operation completely and fails due to limited user privilages (at least I believe so). But I’m getting the following error:
=> [internal] load build context 2.0s
=> => transferring context: 821B 0.6s
=> [2/6] RUN addgroup app && adduser -S -G app app 9.7s
=> [3/6] WORKDIR /app 3.2s
=> [4/6] COPY package*.json . 2.6s
=> ERROR [5/6] RUN npm install 24.7s
------
> [5/6] RUN npm install:
#10 23.08 npm notice
#10 23.08 npm notice New minor version of npm available! 8.3.1 -> 8.17.0
#10 23.08 npm notice Changelog: <https://github.com/npm/cli/releases/tag/v8.17.0>
#10 23.08 npm notice Run `npm install -g [email protected]` to update!
#10 23.08 npm notice
#10 23.08 npm ERR! code EACCES
#10 23.09 npm ERR! syscall open
#10 23.09 npm ERR! path /app/package-lock.json
#10 23.09 npm ERR! errno -13
#10 23.10 npm ERR! Error: EACCES: permission denied, open '/app/package-lock.json'
#10 23.10 npm ERR! [Error: EACCES: permission denied, open '/app/package-lock.json'] {
#10 23.10 npm ERR! errno: -13,
#10 23.10 npm ERR! code: 'EACCES',
#10 23.10 npm ERR! syscall: 'open',
#10 23.10 npm ERR! path: '/app/package-lock.json'
#10 23.10 npm ERR! }
#10 23.10 npm ERR!
#10 23.10 npm ERR! The operation was rejected by your operating system.
#10 23.11 npm ERR! It is likely you do not have the permissions to access this file as the current user
#10 23.11 npm ERR!
#10 23.11 npm ERR! If you believe this might be a permissions issue, please double-check the
#10 23.11 npm ERR! permissions of the file and its containing directories, or try running
#10 23.11 npm ERR! the command again as root/Administrator.
#10 23.11
#10 23.11 npm ERR! A complete log of this run can be found in:
#10 23.12 npm ERR! /home/app/.npm/_logs/2022-08-14T09_27_48_642Z-debug-0.log
------
executor failed running [/bin/sh -c npm install]: exit code: 243
I’m a beginner in docker and learning docker for the first time. I used alpine as the base image and I believe the problem is on the user "app" being created (due to its limited privilege). I saw that its recommended to limit the user which is set to execute the dockerized app. I wanted to do exactly that – to limit the user executing the docker application.
My question is: Is this an update from alpine itself ? (I saw on tutorials that this same dockerfile setup works but not for me… or Am I doing this the wrong way (when creating the user or at any other point)?
Here is my Dockerfile setup
FROM node:16.14.0-alpine3.15
RUN addgroup app && adduser -S -G app app
USER app
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
ENV API=https://apilink.com/someuri
EXPOSE 3000
CMD ["node","app.js"]
2
Answers
Move the
USER
line to the end of the Dockerfile, near where you set theCMD
.What’s happening here is that the
WORKDIR
directive creates the/app
directory, owned by root. When youRUN npm install
, it needs to create thenode_modules
directory. But since you’ve already stepped down to a non-root user, it doesn’t have permission to create that directory and so you get that error.If you specify
USER
last, then the entire build sequence will be run as root, and root will own your application and library files. These files will still be readable by any user, but not writeable. When you then run the container asUSER app
it’s prevented from overwriting your application code, which is a useful security step.I’m going to go against the accepted answer (which incorrectly interprets why the error is happening) and say that you often actually want to add a new user/group before doing anything else (starting with creating the WORKDIR).
The fix is two-fold:
the
app:app
user:group does have the permission for created/app
workdir; however thepackage*.json
files you copy over are owned byroot
user, andapp
user is trying to modify one of them in this case. If you really need the copied files to be modified, you can assign ownership during the copy command like this:COPY --chown=app:app package*.json .
This will allow the build to pass. However:I’d argue that in this specific case, where npm is trying to overwrite something in
package-lock.json
, you don’t actually wan’t this to happen, and should simply replace theRUN npm install
withRUN npm ci
. This will also allow the build to pass.