postinstall "cannot run in wd" when working directory does not match the package name (in docker) #49
Description
What / Why
It is common for a Dockerfile to install an app in a /app
directory. If the app is a node app and it has a "postinstall"
script (and possibly other lifecycle hooks) it will fail with an error that looks like:
npm WARN lifecycle my-example@0.1.0~postinstall: cannot run in wd my-example@0.1.0 npm run exit 0 (wd=/app)
Most of the issues found using a search engine will indicate that this is a permissions issue caused by running as root and npm downgrading permissions to nobody. However, this issue will still occur if the "postinstall" script is "exit 0", which should require no permissions. On the other hand, the suggested workaround of setting --unsafe-perm
works. The relevant lines of code are:
if ((wd.indexOf(opts.dir) !== 0 || _incorrectWorkingDirectory(wd, pkg)) &&
!opts.unsafePerm && pkg.scripts[stage]) {
opts.log.warn('lifecycle', logid(pkg, stage), 'cannot run in wd', pkg._id, pkg.scripts[stage], `(wd=${wd})`)
return resolve()
}
(from index.js, lines 86-90)
Note that employing --unsafe-perm
specifically serves as an escape hatch, though it does not appear to have much to do with permissions on the directory. _incorrectWorkingDirectory()
checks to see if the working directory matches the name of the package in package.json
.
I do not know if this is a bug or intended behavior - it makes sense as a swift heuristic to ensure you are in the expected package - but it is not well documented and conflicts subtly with nodejs.org's recommendations for a Dockerfile.