docker-node
docker-node copied to clipboard
Permission denied error when trying to install pnpm via Corepack as node user
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
Steps to Reproduce
-
Create an empty project with the following
package.json
. ThepackageManager
property is important here.{ "name": "docker-node-pnpm", "version": "1.0.0", "private": true, "packageManager": "[email protected]" }
-
Run the container as a non-privilegied user:
docker run -it -v $(pwd):/app -u node node:lts-alpine /bin/sh
-
cd /app
-
corepack enable
<-- This should fail -
corepack prepare
-
pnpm install
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.
@nodejs/corepack
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.
Opened #1992
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
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")'