I setup a new project inside an alpine image (node:16-alpine
), in /app2
, with the following structure:
- node_modules
- .bin
- dummy
- package.json
package.json:
{
...
"scripts": {
"dummy": "dummy",
},
...
}
dummy:
#!/usr/bin/env node
setInterval(() => console.log("."), 1000)
Now when i run npm run dummy
with root user, instead of the root user, the node command will run with whatever user owns the project root directory. Eg:
/app2 # ls -lah
...
drwxr-xr-x 3 node2 node 4.0K Jan 17 08:27 .
...
/app2 # whoami
root
/app2 # npm run dummy
...
# in a different terminal:
/app2 # ps x
...
816 root 0:00 npm run dummy
827 node2 0:00 node /app2/node_modules/.bin/dummy
...
This does not happen if I'm not running npm with root (eg: su node && npm run dummy
will run as node
user, and not node2
).
Why is this? Does any know if this is documented anywhere? Or how can I run the scripts as root? (i know it's not recommended, but it's inside a docker container and for development only)
This happens in @npmcli/promise-spawn
const isRoot = process.getuid && process.getuid() === 0
const { uid, gid } = isRoot ? inferOwner.sync(cwd) : {}
You cannot find documentation as this behavior was removed a while ago.
This is an old note removed in that commit that described the behavior you see:
Note: When the current user is root, this will use
infer-owner
to find the owner of the current working directory, and run with that effective uid/gid. Otherwise, it runs as the current user always. (This helps prevent doing git checkouts and such, and leaving root-owned files lying around in user-owned locations.)