-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
Is there an existing issue for this?
- I have searched the existing issues
This issue exists in the latest npm version
- I am using the latest npm
Current Behavior
In our build environment, we use docker to perform specific build steps without needing to manage an endless amount of tools on our build agents. The build agents and the steps they execute do not run as root. However, when executing docker run, the user within the ephemeral container is typically root (normal for Docker). We use npm run-script to execute a series of npm commands as part of the build.
The build agent executes docker run --rm -v $PWD:/app -v ~/.npmrc:/root/.npmrc -w /app node:16 sh -c 'npm run-script build'
$PWD contains the checked-out contents from source. We also pass a pre-configured .npmrc shared across all our builds. The contents of $PWD and .npmrc are owned by a non-root uid/gid.
build.sh:
#!/bin/sh
npm install \
&& npm run lint \
&& npm run autotest \
&& rm -rf node_modules \
&& npm install --production
When npm run-script is first executed within the node:16 container, it is running as root (normal for Docker). Once the entrypoint script determines it isn't a node command, npm run-script checks for the existence of the cache folder, which it obviously doesn't find and so creates it (owned by the current user, root) at /root/.npm.
npm then executes build.sh whose first task is to execute npm install (we also tried npm ci). The first thing npm install does is change the user context to the owner of the working directory (/app), which is the non-root user the build agent is using.
npm then checks to see if it can access /root/.npmrc and /root/.npm, which it cannot because the user context has changed.
This user does not exist in node:16's passwd file obviously, so the uid/gid numbers are shown in the error.
npm ERR! code EACCES
npm ERR! syscall lstat
npm ERR! path /root/.npm/_cacache/content-v2/sha1/f2/bb/2a7e83cbc87bb95c8e572828a06c9add6e0d
npm ERR! errno -13
npm ERR!
npm ERR! Your cache folder contains root-owned files, due to a bug in
npm ERR! previous versions of npm which has since been addressed.
npm ERR!
npm ERR! To permanently fix this problem, please run:
npm ERR! sudo chown -R 900:900 "/root/.npm"
This behavior is not observed in versions earlier than node:16.
node:16 comes with npm 8.3.1, but this behavior is still observed when upgrading npm to 8.5.1.
Expected Behavior
Either:
npm run-scriptshouldn't be messing with .npmrc or the cache directory since it doesn't need it
ornpm run-scriptshould be following the same user context switching code path thatnpm installandnpm ciare following.
Steps To Reproduce
- On a machine with Docker installed and running...
- Create a folder containing the following two files. Ensure the folder and files are owned by a non-root user.
package.json:
{
"name": "test-app",
"scripts": {
"build": "./build.sh"
},
"dependencies": {
"config": "^3.1.0"
}
}
build.sh (+x):
#!/bin/sh
id
ls -la
ls -la $HOME
npm install \
&& echo SUCCESS!
- Open a shell as a non-root user and change directories to the folder you just created. Not sure if it would interfere, but try not to use uid/gid 1000 which would map to the
nodeuser withinnode:16. - Run
docker run --rm -v $PWD:/app -w /app node:16 sh -c 'npm -v; node -v; npm config ls; echo -----------; npm run-script build'
Output:
bash-5.1$ docker run --rm -v $PWD:/app -w /app node:16 sh -c 'npm -v; node -v; npm config ls; echo -----------; npm run-script build'
8.3.1
v16.14.0
; node bin location = /usr/local/bin/node
; cwd = /app
; HOME = /root
; Run `npm config ls -l` to show all defaults.
-----------
> build
> ./build.sh
uid=900 gid=900 groups=900
total 8
drwxr-xr-x 2 900 900 42 Feb 21 20:01 .
drwxr-xr-x 1 root root 29 Feb 21 20:28 ..
-rwxr-xr-x 1 900 900 66 Feb 21 20:26 build.sh
-rw-r--r-- 1 900 900 119 Feb 21 18:48 package.json
ls: cannot open directory '/root': Permission denied
glob error [Error: EACCES: permission denied, scandir '/root/.npm/_logs'] {
errno: -13,
code: 'EACCES',
syscall: 'scandir',
path: '/root/.npm/_logs'
}
npm WARN logfile Error: EACCES: permission denied, scandir '/root/.npm/_logs'
npm WARN logfile error cleaning log files [Error: EACCES: permission denied, scandir '/root/.npm/_logs'] {
npm WARN logfile errno: -13,
npm WARN logfile code: 'EACCES',
npm WARN logfile syscall: 'scandir',
npm WARN logfile path: '/root/.npm/_logs'
npm WARN logfile }
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /root/.npm/_cacache/tmp
npm ERR! errno EACCES
npm ERR!
npm ERR! Your cache folder contains root-owned files, due to a bug in
npm ERR! previous versions of npm which has since been addressed.
npm ERR!
npm ERR! To permanently fix this problem, please run:
npm ERR! sudo chown -R 900:900 "/root/.npm"
npm ERR! A complete log of this run can be found in:
npm notice
npm notice New minor version of npm available! 8.3.1 -> 8.5.1
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v8.5.1>
npm notice Run `npm install -g npm@8.5.1` to update!
npm notice
Output with npm upgrade to 8.5.1:
bash-5.1$ docker run --rm -v $PWD:/app -w /app node:16 sh -c 'npm install -g npm; npm -v; node -v; npm config ls; echo -----------; npm run-script build'
removed 1 package, changed 44 packages, and audited 218 packages in 13s
11 packages are looking for funding
run `npm fund` for details
3 moderate severity vulnerabilities
To address all issues, run:
npm audit fix
Run `npm audit` for details.
npm notice
npm notice New minor version of npm available! 8.3.1 -> 8.5.1
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v8.5.1>
npm notice Run `npm install -g npm@8.5.1` to update!
npm notice
8.5.1
v16.14.0
; node bin location = /usr/local/bin/node
; cwd = /app
; HOME = /root
; Run `npm config ls -l` to show all defaults.
-----------
> build
> ./build.sh
uid=900 gid=900 groups=900
total 8
drwxr-xr-x 2 900 900 42 Feb 21 20:01 .
drwxr-xr-x 1 root root 40 Feb 21 20:29 ..
-rwxr-xr-x 1 900 900 66 Feb 21 20:26 build.sh
-rw-r--r-- 1 900 900 119 Feb 21 18:48 package.json
ls: cannot open directory '/root': Permission denied
glob error [Error: EACCES: permission denied, scandir '/root/.npm/_logs'] {
errno: -13,
code: 'EACCES',
syscall: 'scandir',
path: '/root/.npm/_logs'
}
npm WARN logfile Error: EACCES: permission denied, scandir '/root/.npm/_logs'
npm WARN logfile error cleaning log files [Error: EACCES: permission denied, scandir '/root/.npm/_logs'] {
npm WARN logfile errno: -13,
npm WARN logfile code: 'EACCES',
npm WARN logfile syscall: 'scandir',
npm WARN logfile path: '/root/.npm/_logs'
npm WARN logfile }
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /root/.npm/_cacache/tmp
npm ERR! errno EACCES
npm ERR!
npm ERR! Your cache folder contains root-owned files, due to a bug in
npm ERR! previous versions of npm which has since been addressed.
npm ERR!
npm ERR! To permanently fix this problem, please run:
npm ERR! sudo chown -R 900:900 "/root/.npm"
npm ERR! A complete log of this run can be found in:
Environment
- npm: 8.3.1 (part of
node:16), but we tried 8.5.1 as well - Node.js: 16.14.0
- OS Name: Alpine
- System Model Name:
- npm config:
; node bin location = /usr/local/bin/node
; cwd = /app
; HOME = /root
; Run `npm config ls -l` to show all defaults.