Sign inSign up

baredevcontainer/pnpm

By baredevcontainer

•Updated 1 day ago

Minimal Dev Container image for Node.js with pnpm: Debian, verified upstreams, SLSA provenance

Image
Security
Languages & frameworks
Developer tools
0

6.3K

baredevcontainer/pnpm repository overview

⁠pnpm

Mirror. This Docker Hub repository mirrors ghcr.io/bare-devcontainer/pnpm, under the same tags and with the same digests. GitHub Container Registry receives every build first and applies no pull rate limit, so prefer ghcr.io/bare-devcontainer/pnpm unless your environment requires Docker Hub, where the image is docker.io/baredevcontainer/pnpm.

This page is rendered from the image's README in bare-devcontainer/images⁠. That is the repository "this repository" refers to below.

Dev container image with pnpm⁠ installed, built on the debian⁠ base image. pnpm installs the Node.js version the project asks for, so the runtime is chosen by the project rather than baked into the image.

Like every image in this repository, it is minimal, built only from upstreams verified at build time, and published with SLSA provenance, a GitHub artifact attestation, and an SBOM; it runs as the non-root user dev. Why these images⁠ explains the reasoning, and Verifying the image⁠ below shows how to check a build.

⁠Image

ghcr.io/bare-devcontainer/pnpm:<tag>

Reference it from .devcontainer/devcontainer.json, pinning the digest as well as the tag:

{
  "image": "ghcr.io/bare-devcontainer/pnpm:12@sha256:<digest>"
}

⁠Dev Container Template

A ready-to-use Dev Container template for this image is available at bare-devcontainer/templates⁠. It provides the recommended configuration for this image, including security hardening and volume mounts that persist cache directories for faster rebuilds.

⁠Tags

TagsDebian variant
12.7.0-trixie, 12-trixie, 12.7.0, 12, trixietrixie
12.7.0-bookworm, 12-bookworm, bookwormbookworm

Tags are also published with a date suffix on each build (e.g., 12.7.0-trixie-<YYYYMMDD>).

The version in these tags is the version of pnpm itself, not of any Node.js runtime.

⁠Installed software

Everything from the debian⁠ base image, plus:

  • pnpm⁠ (pnpm), with bash completions installed

pnpm is installed under /opt/pnpm with a /usr/local/bin/pnpm symlink, the layout of pnpm's own ghcr.io/pnpm/pnpm⁠ image. Under a Dev Container client, PNPM_HOME is ~/.local/share/pnpm and its bin directory is on PATH, so runtimes and globally installed packages resolve without further setup. Running the image without one (docker run, a CI job's container:) declares neither, so a global install needs both set first.

⁠Not installed

  • No Node.js. pnpm downloads and manages the runtime the project declares in devEngines.runtime⁠, so the version in use is the one the project asks for. See Working with runtimes⁠ below.
  • No npm, npx, or Corepack. pnpm covers those workflows, and installing a Node.js runtime with pnpm deliberately leaves the bundled npm unextracted. Run pnpm add -g npm if a project needs it. For a project whose package manager is not pnpm, use the node⁠ image instead.
  • No global JavaScript tooling. Linters, formatters, and test runners are left to the project's own dependencies.

⁠Working with runtimes

Declare the runtime in the project's package.json and pnpm installs it on first use:

{
  "devEngines": {
    "runtime": { "name": "node", "version": "^24.0.0", "onFail": "download" }
  }
}

Inside that project a bare node runs the pinned version, because pnpm's global node is a shim that dispatches to what the project asks for. Outside any project it runs the globally installed version, which is set with pnpm runtime⁠:

pnpm runtime set node lts -g

To install the project's runtime and dependencies when the container is created rather than on first use, run pnpm install from a postCreateCommand.

Two directories are worth persisting across container rebuilds as volumes:

  • ~/.local/share/pnpm — the store, the managed runtimes, and the bins of globally installed packages. All of it is re-downloaded on every rebuild unless this directory survives.
  • ~/.cache/pnpm — the metadata cache.

⁠Supply chain

pnpm is downloaded from GitHub Releases⁠, the same archive pnpm's own container image installs, and verified against a checksum committed to this repository (pnpm/pnpm-amd64.sha256, pnpm/pnpm-arm64.sha256).

pnpm publishes neither a checksum nor a detached signature, so that checksum is not fetched from upstream — it is derived here, and only from an archive whose origin has been established. .github/workflows/update-material.yml runs pnpm/checksum.sh whenever the pinned version changes, and the script records a digest only after gh attestation verify has confirmed that the archive's build provenance⁠ was signed by pnpm's release workflow at that version's tag. The resulting checksum is committed and reviewed like any other change, so what the image build trusts is a digest this repository accepted, rather than one the release host served alongside the archive.

Note that this covers the pnpm binary only. Runtimes and packages that pnpm installs at runtime are fetched from their own upstreams under pnpm's own verification, outside this image's build pipeline.

⁠Verifying the image

Every build is published with SLSA provenance, a GitHub artifact attestation, and an SBOM. The attestation confirms that an image was built by the release workflow of this repository and has not been altered since:

gh attestation verify oci://ghcr.io/bare-devcontainer/pnpm:<tag>@sha256:<digest> \
  --owner bare-devcontainer

The Docker Hub mirror carries the same digests, so the same command verifies an image pulled from docker.io/baredevcontainer/pnpm. Verifying Published Images⁠ covers inspecting the provenance and the SBOM as well.

Tag summary

Content type

Image

Digest

sha256:5e796fce8…

Size

247.6 MB

Last updated

1 day ago

docker pull baredevcontainer/pnpm:12.7.0-bookworm