No access permission error with npm global install on docker image

Use the --unsafe-perm flag:

npm install --quiet --no-progress --unsafe-perm -g @angular/cli@latest firebase-tools

I think that's still better than setting the npm user permanently to root. You can use --unsafe-perm only with the packages which cause problem


Please DO NOT set the user to root or use --unsafe-perm.

Simply use the node user, provided with the current official (e.g. alpine) images.

Commented Dockerfile below:

FROM node:15.5-alpine

# 👉 Security: do not use the `root` user.
ENV USER=node

# You can not use `${USER}` here, but reference `/home/node`.
ENV PATH="/home/node/.npm-global/bin:${PATH}"
# 👉 The `--global` install dir
ENV NPM_CONFIG_PREFIX="/home/node/.npm-global"

# All subsequent commands are run as the `node` user.
USER "${USER}"

# Pre-create the target dir for global install.
RUN mkdir -p "${NPM_CONFIG_PREFIX}/lib"

WORKDIR /usr/src/app

COPY package.json package-lock.json ./

# 👉 Configure NPM, so pkg get installed with correct credentials.
# Avoids `chmod u+x $DIR` and other workarounds.
RUN npm --global config set user "${USER}" \
    && npm --global --quiet --no-progress install \
    && npm cache clean --force

Extended version of @gabriel-araujo answer.

You can replace setting the user via the CLI flags (npm --global config set user "${USER}") by configuring this in the .npmrc file. Place user=node in the project roots .npmrc file or just set it directly from the Dockerfile.

RUN echo "user=node" > "${NPM_CONFIG_PREFIX}/etc/.npmrc"

If you use docker-compose.yml, you can add it as environment: - … variable.

Hope that helps you running a more safe NodeJS container somewhere and pull up some awesome stuff.


The problem is because while NPM runs globally installed module scripts as the nobody user, which kinds of makes sense, recent versions of NPM started setting the file permissions for node modules to root. As a result module scripts are no longer allowed to create files and directories in their module.

See discussion in NPM issue #3849, for some references.

A simple workaround, which makes sense in a docker environment, is to set the NPM default global user back to root, like so:

npm -g config set user root

After which you shouldn't have any more EACCES errors.

Tags:

Docker

Npm