Docker
Official nub Docker images, and how to add nub to your own image. The images install nub onto an official node base, so Node is present and the runtime is augmented out of the box.
Nub augments the Node already in your image — it is not a separate runtime. The official images start from an official node base and layer nub on top, so node, npm, and nub are all present.
Official images
FROM ghcr.io/nubjs/nub
COPY --chown=node:node . .
RUN nub install
CMD ["nub", "run", "start"]The image runs as the non-root node user, so copy your project in with --chown=node:node — a bare COPY . . lands root-owned files that nub install then can't write alongside.
Two variants, both on the current Node release line, digest-pinned and published for linux/amd64 and linux/arm64:
| Tag | Base | libc |
|---|---|---|
latest, <version>, slim, <version>-slim | node:26-slim | glibc |
alpine, <version>-alpine | node:26-alpine | musl |
Run a TypeScript file directly — the entrypoint passes any non-command argument to nub:
docker run --rm -v "$PWD:/app" ghcr.io/nubjs/nub script.tsSignals reach the runtime: docker stop delivers SIGTERM to nub, which forwards it to the Node process for a clean shutdown. The container runs as the non-root node user (uid 1000); when you bind-mount a directory that nub install must write into, run with --user "$(id -u)" so the writes land with your host ownership.
Adding nub to your own image
If you already build on a node base, install nub with one line. npm selects the correct per-platform binary at install time — including the musl build on Alpine — and the package's postinstall sets the execute bit, so installing as root and then dropping to a non-root user works.
FROM node:26-slim
RUN npm install -g @nubjs/nubOn Alpine, add libgcc and libstdc++ for the native addon:
FROM node:26-alpine
RUN apk add --no-cache libgcc libstdc++ && npm install -g @nubjs/nubTo pin the floor Node version instead of the current line, use a 22 base (node:22-slim or node:22-alpine) — the lowest version nub's fast tier supports.