The FROM line decides most of an image's size, its security exposure and how pleasant it is to debug. For a Node.js 2,131 service like BookNest there are five realistic candidates, all pulled and measured on this host with docker image ls:
| Image | Download | Base, C library | Shell and package manager |
|---|---|---|---|
| node:24 | 426 MB | Debian 319 , glibc | Yes; compilers and build tools too |
| node:24-slim | 83 MB | Debian 12, glibc | Yes (apt), no build tools |
| node:24-alpine | 62 MB | Alpine 13,255 , musl | Yes (apk) |
| gcr.io/distroless/nodejs24-debian13 | 55 MB | Debian 13, glibc | None; root by default, :nonroot tag |
| cgr.dev/chainguard/node | 69 MB | Wolfi 1,291 , glibc | BusyBox 65,982 shell; free tier offers latest only |
The full node:24 image carries compilers only a build stage needs. node:24-alpine is the smallest with a shell, but musl occasionally breaks native add-ons. Distroless 23,100 images from Google (GoogleContainerTools/distroless (https://github.com/GoogleContainerTools/distroless 23,100 )) contain the runtime and nothing else: no shell for an attacker to use, and nothing for a vulnerability scanner to flag, but also nothing for you to debug with. Chainguard 179,813 images are rebuilt daily for a near-zero CVE count, and Docker 514 's own Hardened Images (dhi.io) aim at the same goal but require a Docker login even for the free ones (an anonymous pull here failed with 401 Unauthorized). Chainguard's free latest tag already runs Node.js 26.10.0 (node -e 'console.log(process.version)'), a reminder that "latest" means "whatever was built last".
BookNest Dockerfile's Dockerfile for BookNest's API uses node:24-slim: glibc, a shell for debugging, 83 MB, and the same Debian family as postgres:18.