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. At install time, npm selects the correct per-platform binary — 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.
Multi-stage builds
Install with nub ci in the build stage. It writes a self-contained node_modules — real files, project-local links — that survives a COPY --from into the final stage. A plain nub install shares packages through a machine-global store the final stage doesn't have, so the copied tree would point at files that aren't there.
FROM node:26-slim AS build
RUN npm install -g @nubjs/nub
WORKDIR /app
COPY . .
RUN nub ci
FROM node:26-slim
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY . .
CMD ["nub", "run", "start"]