Files
pnpm/docker/README.md
Zoltan Kochan 9ae1ca7253 feat: publish base docker image to GHCR (#11302)
* feat: publish base docker image to GHCR

Adds a Dockerfile (debian:stable-slim + pnpm standalone binary) and a
release-triggered workflow that builds multi-arch images and pushes to
ghcr.io/pnpm/pnpm. Users who need Node.js can install it inside the
container via `pnpm runtime set node <version>`.

Refs #11300

* docs: add docker/README.md

* chore(cspell): add buildx to dictionary

* docs: mention devEngines.runtime as alternative to pnpm runtime set

* fix(docker): pin base image, verify tarball sha256, harden download

- Pin `debian:stable-slim` to a digest for reproducibility.
- Compute pnpm tarball SHA256 in the workflow and verify it inside the
  build, detecting tampered artifacts regardless of what `pnpm --version`
  reports.
- Download the tarball to disk with `--retry` instead of `curl | tar`
  for resilience under multi-arch QEMU builds.
- README: use `--load` so the local test image is available to `docker run`.

* chore(cspell): sort dictionary additions

* fix(docker): address Copilot review feedback

- Include $PNPM_HOME/bin on PATH so pnpm-installed globals (node, etc.)
  are discoverable, and make $PNPM_HOME writable for non-root users.
- Document that `pnpm runtime set node` needs `-g` to install globally.
- Pass workflow inputs via env: instead of inlining GitHub expressions
  into shell, and validate the version string before use.

* fix(docker): install libatomic1 for pnpm standalone binary

The pnpm linux standalone binary dynamically links against
libatomic.so.1, which is not present in debian:stable-slim by
default. Without it, `pnpm --version` fails during the build with:

  pnpm: error while loading shared libraries: libatomic.so.1:
  cannot open shared object file: No such file or directory

Caught by local build testing.
2026-04-19 18:59:24 +02:00

77 lines
2.2 KiB
Markdown

# pnpm base Docker image
Official base image for pnpm, published to GitHub Container Registry.
```
ghcr.io/pnpm/pnpm
```
Based on `debian:stable-slim` with the pnpm standalone binary. Node.js is **not** bundled — install the version you need inside your own image with `pnpm runtime set node <version> -g` (the `-g` flag makes `node` available on `PATH` for subsequent layers and at runtime).
## Tags
| Tag | Meaning |
| --------------------- | ----------------------------------------------------------------------- |
| `<version>` | Exact, immutable (e.g. `11.0.0`). Includes prereleases. |
| `<major>` | Tracks the latest stable release within that major (e.g. `11`). |
| `latest` | Most recent stable pnpm release. Not updated for prereleases. |
## Supported platforms
`linux/amd64`, `linux/arm64`.
## Usage
Install Node.js explicitly with `pnpm runtime set`:
```dockerfile
FROM ghcr.io/pnpm/pnpm:latest
RUN pnpm runtime set node 22 -g
WORKDIR /app
COPY . .
RUN pnpm install --frozen-lockfile
CMD ["node", "index.js"]
```
Or let pnpm install Node.js from `devEngines.runtime` in your `package.json`:
```json
{
"devEngines": {
"runtime": {
"name": "node",
"version": "22.x",
"onFail": "download"
}
}
}
```
```dockerfile
FROM ghcr.io/pnpm/pnpm:latest
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
CMD ["pnpm", "start"]
```
## Build locally
```sh
VERSION=11.0.0-rc.2
SHA=$(curl -fsSL "https://github.com/pnpm/pnpm/releases/download/v${VERSION}/pnpm-linux-x64.tar.gz" \
| sha256sum | awk '{print $1}')
docker buildx build \
--build-arg PNPM_VERSION=${VERSION} \
--build-arg PNPM_SHA256_AMD64=${SHA} \
--platform linux/amd64 \
--load \
-t pnpm-test ./docker
docker run --rm pnpm-test pnpm --version
```
## Release
Images are built and pushed by [`.github/workflows/docker.yml`](../.github/workflows/docker.yml) on `release: published`, or manually via `workflow_dispatch`. The build fails if `pnpm --version` in the image doesn't match the `PNPM_VERSION` build-arg.