When installation of global package using npm inside Docker fails

Aleksandr Guidrevitch
2 min readNov 26, 2017

--

It happens, that official Docker image of node fails to install some packages globally, one of them is nodegit:

$docker run --rm -it node:carbon npm -g install nodegit> nodegit@0.20.3 install /usr/local/lib/node_modules/nodegit
> node lifecycleScripts/preinstall && node lifecycleScripts/install
...
/usr/local/lib/node_modules/nodegit/vendor/libssh2/configure: line 2069: config.log: Permission denied

The same issue is triggered when Dockerfile contains:

FROM node:carbon
RUN npm -g install nodegit

It turns out that when you run npm as root to install a global package, it installs and executes binaries, as user ‘nobody’

In many Unix variants, “nobody” is the conventional name of a user account which owns no files, is in no privileged groups, and has no abilities except those which every other user has. https://en.wikipedia.org/wiki/Nobody_(username)

Obviously, ‘nobody’ normally doesn’t have permissions to write to the /usr/local directory, and this is why ‘Permissin denied’ is reported. There are 2 solutions to this issue:

  1. One-time solution is to use npm’s --unsafe-perm switch, in Dockerfile
RUN npm -g install nodegit --unsafe-perm

2. Allow npm to install binaries owned by the root user, in Dockerfile:

RUN npm -g config set user root
RUN npm -g install nodegit

Hope it saves a few hours of headache for someone who gets unexplained ‘Permission Denied’ errors when installing npm packages globally.

If you’ve found this post because you have problems building nodegit specifically, here are the other missing pieces — if you are not using official node docker images, you will also need to install curl, libcurl4-openssl-dev, and libssl-dev on debian or their alternatives on other distros to build nodegit.

--

--