fix(docker): link the pn, pnpx, and pnx aliases in the image (#17282)

docker/install-pnpm.sh linked only `pnpm` into /usr/local/bin, so the
image had no `pn`, `pnpx`, or `pnx`. The script now hardlinks the
binary as each alias in /opt/pnpm and symlinks them onto PATH, as the
npm package and self-update do for the native binary. Both the v12
binary and the v11 executable read the launch name from the hardlink
and run `pnpm dlx` for `pnpx` and `pnx`. The docs recipe for copying
/opt/pnpm into another image links the aliases too. The install
script fails the build if `pn` does not print the installed version or
`pnpx` and `pnx` do not run `pnpm dlx`.

Fixes pnpm/pnpm#17275

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-24 00:32:19 +02:00
1 parent 5cefdc7810
commit dd8a695bde
3 files changed
+21 -8

No files matched your search

+1 -1
View File
@@ -26,7 +26,7 @@ To add pnpm to an existing image, such as `node:<version>-alpine`, copy the whol
```dockerfile
FROM node:24-alpine
COPY --from=ghcr.io/pnpm/pnpm:12-alpine /opt/pnpm /opt/pnpm
RUN ln -s /opt/pnpm/pnpm /usr/local/bin/pnpm
RUN for bin in pnpm pn pnpx pnx; do ln -s "/opt/pnpm/$bin" "/usr/local/bin/$bin"; done
```
## Supported platforms
+18 -5
View File
@@ -30,8 +30,21 @@ test "$actual_sha" = "$expected_sha" || {
tar -xzf /tmp/pnpm.tgz -C /opt/pnpm
rm /tmp/pnpm.tgz
ln -s /opt/pnpm/pnpm /usr/local/bin/pnpm
installed="$(pnpm --version)"
test "$installed" = "$PNPM_VERSION" || {
echo "pnpm version mismatch: expected $PNPM_VERSION, got $installed" >&2
exit 1
}
for alias in pn pnpx pnx; do
ln /opt/pnpm/pnpm "/opt/pnpm/$alias"
ln -s "/opt/pnpm/$alias" "/usr/local/bin/$alias"
done
for bin in pnpm pn; do
installed="$("$bin" --version)"
test "$installed" = "$PNPM_VERSION" || {
echo "$bin version mismatch: expected $PNPM_VERSION, got $installed" >&2
exit 1
}
done
for alias in pnpx pnx; do
help="$("$alias" --help)"
case "$help" in
*"pnpm dlx"*) ;;
*) echo "$alias does not run pnpm dlx" >&2; exit 1 ;;
esac
done
+2 -2
View File
@@ -33,13 +33,13 @@ Supported platforms: `linux/amd64`, `linux/arm64`.
### Adding pnpm to your own image
Copy `/opt/pnpm` from the image whose C library matches your base image, and link the binary onto `PATH`.
Copy `/opt/pnpm` from the image whose C library matches your base image, and link the binary and its `pn`, `pnpx`, and `pnx` aliases onto `PATH`.
Copy the whole directory, because it also contains the `node-gyp` that pnpm uses to build native dependencies.
```dockerfile title="Dockerfile"
FROM node:24-alpine
COPY --from=ghcr.io/pnpm/pnpm:12-alpine /opt/pnpm /opt/pnpm
RUN ln -s /opt/pnpm/pnpm /usr/local/bin/pnpm
RUN for bin in pnpm pn pnpx pnx; do ln -s "/opt/pnpm/$bin" "/usr/local/bin/$bin"; done
```
For a Debian- or Ubuntu-based image, such as `node:24-slim`, copy from `ghcr.io/pnpm/pnpm:12` instead.