Search code examples
javascriptnode.jsdockernpmpnpm

PNPM docker non-root user Permission Denied


I just found about pnpm today and it helped solve my issue with npm timing out on my installation which is amazing. I've a problem with pnpm tho in the docker image.

Previously with just npm I had unprivileged user like so

FROM node:14.17.3-slim

# build args
ARG NPM_AUTH_TOKEN
ARG HOME=/home/app
ARG NPMRC_PATH=$HOME/.npmrc

# setup unprivileged user
RUN useradd -Umrd $HOME app
WORKDIR $HOME
USER app

# copy configuration
COPY --chown=app:app "bin" "bin"
COPY --chown=app:app "package.json" "package-lock.json" "webpack.config.js" ".babelrc" ./

RUN ./bin/write_npmrc && \
    npm ci --production=false

ENV NODE_ENV=development
VOLUME ["$HOME/config", "$HOME/log", "$HOME/src"]
CMD ["npm", "start"]
EXPOSE 9000

But if I switch to the pnpn I'm no longer able to proceed with building the image due to Permission Denied and I need to use root user.

FROM node:14.17.3-slim

# build args
ARG NPM_AUTH_TOKEN
ARG HOME=/home/app
ARG NPMRC_PATH=$HOME/.npmrc

RUN apt-get update && apt-get install -y curl \
 && rm -rf /var/lib/apt/lists/*
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm

WORKDIR $HOME

# copy configuration
COPY "bin" "bin"
COPY "package.json" "pnpm-lock.yaml" "webpack.config.js" ".babelrc" ./

RUN ./bin/write_npmrc && \
    pnpm install --frozen-lockfile

ENV NODE_ENV=development
VOLUME ["$HOME/config", "$HOME/log", "$HOME/src"]
CMD ["pnpm", "start"]
EXPOSE 9000

Is there a way so I can keep

# setup unprivileged user
    RUN useradd -Umrd $HOME app
    WORKDIR $HOME
    USER app

With pnpm instead?


Solution

  • You just need to change to your non-privileged user after installing the system packages.

    Example:

    FROM node:14.17.3-slim
    
    # build args
    ARG NPM_AUTH_TOKEN
    ARG HOME=/home/app
    ARG NPMRC_PATH=$HOME/.npmrc
    
    RUN apt-get update && apt-get install -y curl \
     && rm -rf /var/lib/apt/lists/*
    
    RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
    
    # setup unprivileged user
    RUN useradd -Umrd $HOME app && \
        chown -R app:app $HOME
    WORKDIR $HOME
    USER app
    
    # copy configuration
    COPY --chown=app:app "bin" "bin"
    COPY --chown=app:app "package.json" "pnpm-lock.yaml" "webpack.config.js" ".babelrc" ./
    
    RUN ./bin/write_npmrc && \
        pnpm install --frozen-lockfile
    
    ENV NODE_ENV=development
    VOLUME ["$HOME/config", "$HOME/log", "$HOME/src"]
    CMD ["pnpm", "start"]
    EXPOSE 9000