Skip to content

Commit b9f7af4

Browse files
committed
Add example for Debian without npm or Yarn
1 parent a15e208 commit b9f7af4

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

docs/BestPractices.md

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,20 @@ FROM node:alpine as app
207207
COPY --from=builder node_modules .
208208
```
209209

210-
211210
## Smaller images without npm/yarn
212211

213-
If you want to achieve an even smaller image size than the `-alpine`, you can omit the npm/yarn like this:
212+
To remove npm and Yarn package managers, use a multi-stage build.
213+
In the first stage, the package manager builds the app.
214+
In the second stage, the `app` and the `node` directories are copied,
215+
without copying the npm & Yarn package managers.
216+
In Docker images based on Node.js >=26, Yarn is already removed.
217+
218+
The result is a smaller and hardened final image with no package managers.
219+
The size savings are typically about 2% or 3%.
220+
221+
The examples below build with npm.
222+
223+
**Alpine example**
214224

215225
```Dockerfile
216226
ARG ALPINE_VERSION=3.23
@@ -219,7 +229,7 @@ FROM node:24-alpine${ALPINE_VERSION} AS builder
219229
WORKDIR /build-stage
220230
COPY package*.json ./
221231
RUN npm ci
222-
# Copy the the files you need
232+
# Copy the files you need
223233
COPY . ./
224234
RUN npm run build
225235

@@ -240,3 +250,34 @@ COPY --from=builder /build-stage/dist ./dist
240250
# Run with dumb-init to not start node with PID=1, since Node.js was not designed to run as PID 1
241251
CMD ["dumb-init", "node", "dist/index.js"]
242252
```
253+
254+
**Debian example**
255+
256+
```Dockerfile
257+
FROM node:24-trixie-slim AS builder
258+
WORKDIR /build-stage
259+
COPY package*.json ./
260+
RUN npm ci
261+
# Copy the files you need
262+
COPY . ./
263+
RUN npm run build
264+
265+
FROM debian:trixie-slim
266+
# Create app directory
267+
WORKDIR /usr/src/app
268+
# Add required binaries
269+
RUN apt-get update && apt-get install -y --no-install-recommends dumb-init \
270+
&& rm -rf /var/lib/apt/lists/* \
271+
&& groupadd --gid 1000 node \
272+
&& useradd --uid 1000 --gid node --shell /bin/bash --create-home node \
273+
&& chown node:node ./
274+
COPY --from=builder /usr/local/bin/node /usr/local/bin/
275+
COPY --from=builder /usr/local/bin/docker-entrypoint.sh /usr/local/bin/
276+
ENTRYPOINT ["docker-entrypoint.sh"]
277+
USER node
278+
# Update the following COPY lines based on your codebase
279+
COPY --from=builder /build-stage/node_modules ./node_modules
280+
COPY --from=builder /build-stage/dist ./dist
281+
# Run with dumb-init to not start node with PID=1, since Node.js was not designed to run as PID 1
282+
CMD ["dumb-init", "node", "dist/index.js"]
283+
```

0 commit comments

Comments
 (0)