docker-node icon indicating copy to clipboard operation
docker-node copied to clipboard

Permission denied error when trying to install pnpm via Corepack as node user

Open bgondy opened this issue 2 years ago • 6 comments

Environment

  • Node.js Version: 16.15.0
  • Image Tag: lts-alpine

Expected Behavior

I should be able to install pnpm using Corepack as a non-privilegied user.

Current Behavior

When I try to install pnpm via Corepack (corepack enable) as non-privilegied user (-u node), I get the following error:

/app $ corepack enable
Internal Error: EACCES: permission denied, symlink '../lib/node_modules/corepack/dist/pnpm.js' -> '/usr/local/bin/pnpm'
Error: EACCES: permission denied, symlink '../lib/node_modules/corepack/dist/pnpm.js' -> '/usr/local/bin/pnpm'
/app $ 

Running corepack enable as root work as expected.

docker run -it -v $(pwd):/app node:lts-alpine /bin/sh

image

Steps to Reproduce

  1. Create an empty project with the following package.json. The packageManager property is important here.

    {
        "name": "docker-node-pnpm",
        "version": "1.0.0",
        "private": true,
        "packageManager": "[email protected]"
    }
    
  2. Run the container as a non-privilegied user: docker run -it -v $(pwd):/app -u node node:lts-alpine /bin/sh

  3. cd /app

  4. corepack enable <-- This should fail

  5. corepack prepare

  6. pnpm install

bgondy avatar Jun 03 '22 13:06 bgondy

For now, I've found a workaround by building my own image on top of node:lts-alpine and running corepack enable (as root) during build.

FROM node:lts-alpine

RUN corepack enable

Then, I'm able to run corepack prepare && corepack enable and pnpm as a non-privilegied user.

bgondy avatar Jun 03 '22 16:06 bgondy

@nodejs/corepack

nschonni avatar Jun 03 '22 16:06 nschonni

I think this would best solved at image build-time by adding following cmd to Dockerfile(s):

chgrp 1000 /usr/local/bin && chmod g+w /usr/local/bin

I maintain a suite of private org-level images which extend docker.io/_/node:{18,20}, and that's what I did.

Proper ACLs (via setfacl) would be probably be best, but unlikely that'll be available for all targets/upstreams. Unless maintainers are opposed to granting group=node write perms to /usr/local/bin, i don't think there's a simpler way.

eckdanny avatar Oct 31 '23 17:10 eckdanny

Opened #1992

eckdanny avatar Oct 31 '23 19:10 eckdanny

I agree with @meyfa's PR feedback. The private org-level images i mentioned are ephemeral runtimes to generate statics (fine for my use case) but anyone using docker.io/_/node imgs for runtime workloads should be justifiably concerned.

💡 I think there may be a precedent in the homebrew ecosystem worth looking into.

💡 I don't know how/where corepack determines where to writes symlinks, but hopefully its user-aware and we might try giving $PATH precedence to $USER/bin.

Open to suggestions that wouldn't compromise root.root ownership of /usr/local/bin w/o introducing ACLs

eckdanny avatar Oct 31 '23 20:10 eckdanny

Alternatively, you can use a custom entrypoint like this:

#!/usr/bin/env bash
corepack enable

su - node && corepack prepare && pnpm install && $@
docker run --rm -v ./entrypoint.sh:/entrypoint.sh --entrypoint /entrypoint.sh -v ./app:/home/node/app -w /home/node/app node:16 node -e 'console.log("test")'

LaurentGoderre avatar Nov 01 '23 19:11 LaurentGoderre