recipes / container-images / buildpacks

Build an image with Cloud Native Buildpacks

Get a production Node.js image without writing a Dockerfile, using pack and Paketo.

Buildpacks detect a Node.js project, install dependencies, and produce an OCI image with a non-root user, a launcher that forwards signals, and a rebasable base image. You still get to pick what runs as the process.

Build

pack build ghcr.io/you/app:1.0.0 \
  --builder paketobuildpacks/builder-jammy-base \
  --env BP_NODE_VERSION=24.*

Tell it what to run

Without a Procfile, Paketo runs npm start. Override it:

# Procfile
web: node src/server.js

Or set it in project.toml and avoid extra flags:

# project.toml
[_]
schema-version = "0.2"

[[io.buildpacks.build.env]]
name = "BP_NODE_VERSION"
value = "24.*"

[[io.buildpacks.build.env]]
name = "BP_NODE_PROJECT_PATH"
value = "."

Notes

  • The launcher is PID 1 and forwards SIGTERM to your process. Your shutdown handler still applies.
  • Dev dependencies are pruned when NODE_ENV=production, which Paketo sets by default.
  • pack rebase swaps the run image for a patched one without rebuilding your layers.
  • Trade-off: the run image is Ubuntu based and includes a shell. Smaller than most hand-written images, but not distroless.

See it applied

Updated 2026-09-10 · tags: buildpacks, paketo, build · edit on GitHub