Skip to content

Commit bbfd649

Browse files
[feat] update node.js guide to use dhi image example also
1 parent 281cc11 commit bbfd649

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

content/guides/nodejs/containerize.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,161 @@ These updates help ensure your app is easy to deploy, fast to load, and producti
312312

313313
### Step 2: Configure the Dockerfile file
314314

315+
Before creating a Dockerfile, you need to choose a base image. You can either use the [Node.js Official Image](https://hub.docker.com/_/node) or a Docker Hardened Image (DHI) from the [Hardened Image catalog](https://hub.docker.com/hardened-images/catalog).
316+
317+
Choosing DHI offers the advantage of a production-ready image that is lightweight and secure. For more information, see [Docker Hardened Images](https://docs.docker.com/dhi/).
318+
319+
{{< tabs >}}
320+
{{< tab name="Using Docker Hardened Images" >}}
321+
Docker Hardened Images (DHIs) are available for Node.js on [Docker Hub](https://hub.docker.com/hardened-images/catalog/dhi/node). Unlike using the Docker Official Image, you must first mirror the Node.js image into your organization and then use it as your base image. Follow the instructions in the [DHI quickstart](/dhi/get-started/) to create a mirrored repository for Node.js.
322+
323+
Mirrored repositories must start with `dhi-`, for example: `FROM <your-namespace>/dhi-node:<tag>`. In the following Dockerfile, the `FROM` instruction uses `<your-namespace>/dhi-node:22` as the base image.
324+
325+
```dockerfile
326+
# ========================================
327+
# Optimized Multi-Stage Dockerfile
328+
# Node.js TypeScript Application (Using DHI)
329+
# ========================================
330+
331+
FROM <your-namespace>/dhi-node:22 AS base
332+
333+
# Set working directory
334+
WORKDIR /app
335+
336+
# Create non-root user for security
337+
RUN addgroup -g 1001 -S nodejs && \
338+
adduser -S nodejs -u 1001 -G nodejs && \
339+
chown -R nodejs:nodejs /app
340+
341+
# ========================================
342+
# Dependencies Stage
343+
# ========================================
344+
FROM base AS deps
345+
346+
# Copy package files
347+
COPY package*.json ./
348+
349+
# Install production dependencies
350+
RUN --mount=type=cache,target=/root/.npm,sharing=locked \
351+
npm ci --omit=dev && \
352+
npm cache clean --force
353+
354+
# Set proper ownership
355+
RUN chown -R nodejs:nodejs /app
356+
357+
# ========================================
358+
# Build Dependencies Stage
359+
# ========================================
360+
FROM base AS build-deps
361+
362+
# Copy package files
363+
COPY package*.json ./
364+
365+
# Install all dependencies with build optimizations
366+
RUN --mount=type=cache,target=/root/.npm,sharing=locked \
367+
npm ci --no-audit --no-fund && \
368+
npm cache clean --force
369+
370+
# Create necessary directories and set permissions
371+
RUN mkdir -p /app/node_modules/.vite && \
372+
chown -R nodejs:nodejs /app
373+
374+
# ========================================
375+
# Build Stage
376+
# ========================================
377+
FROM build-deps AS build
378+
379+
# Copy only necessary files for building (respects .dockerignore)
380+
COPY --chown=nodejs:nodejs . .
381+
382+
# Build the application
383+
RUN npm run build
384+
385+
# Set proper ownership
386+
RUN chown -R nodejs:nodejs /app
387+
388+
# ========================================
389+
# Development Stage
390+
# ========================================
391+
FROM build-deps AS development
392+
393+
# Set environment
394+
ENV NODE_ENV=development \
395+
NPM_CONFIG_LOGLEVEL=warn
396+
397+
# Copy source files
398+
COPY . .
399+
400+
# Ensure all directories have proper permissions
401+
RUN mkdir -p /app/node_modules/.vite && \
402+
chown -R nodejs:nodejs /app && \
403+
chmod -R 755 /app
404+
405+
# Switch to non-root user
406+
USER nodejs
407+
408+
# Expose ports
409+
EXPOSE 3000 5173 9229
410+
411+
# Start development server
412+
CMD ["npm", "run", "dev:docker"]
413+
414+
# ========================================
415+
# Production Stage
416+
# ========================================
417+
ARG NODE_VERSION=22.21.0-alpine3.21
418+
FROM node:${NODE_VERSION} AS production
419+
420+
# Set working directory
421+
WORKDIR /app
422+
423+
# Create non-root user for security
424+
RUN addgroup -g 1001 -S nodejs && \
425+
adduser -S nodejs -u 1001 -G nodejs && \
426+
chown -R nodejs:nodejs /app
427+
428+
# Set optimized environment variables
429+
ENV NODE_ENV=production \
430+
NODE_OPTIONS="--max-old-space-size=256 --no-warnings" \
431+
NPM_CONFIG_LOGLEVEL=silent
432+
433+
# Copy production dependencies from deps stage
434+
COPY --from=deps --chown=nodejs:nodejs /app/node_modules ./node_modules
435+
COPY --from=deps --chown=nodejs:nodejs /app/package*.json ./
436+
# Copy built application from build stage
437+
COPY --from=build --chown=nodejs:nodejs /app/dist ./dist
438+
439+
# Switch to non-root user for security
440+
USER nodejs
441+
442+
# Expose port
443+
EXPOSE 3000
444+
445+
# Start production server
446+
CMD ["node", "dist/server.js"]
447+
448+
# ========================================
449+
# Test Stage
450+
# ========================================
451+
FROM build-deps AS test
452+
453+
# Set environment
454+
ENV NODE_ENV=test \
455+
CI=true
456+
457+
# Copy source files
458+
COPY --chown=nodejs:nodejs . .
459+
460+
# Switch to non-root user
461+
USER nodejs
462+
463+
# Run tests with coverage
464+
CMD ["npm", "run", "test:coverage"]
465+
```
466+
467+
{{< /tab >}}
468+
{{< tab name="Using the official Docker image" >}}
469+
315470
Now you need to create a production-ready multi-stage Dockerfile. Replace the generated Dockerfile with the following optimized configuration:
316471

317472
```dockerfile
@@ -456,6 +611,9 @@ USER nodejs
456611
# Run tests with coverage
457612
CMD ["npm", "run", "test:coverage"]
458613
```
614+
{{< /tab >}}
615+
616+
{{< /tabs >}}
459617

460618
Key features of this ultra-optimized Dockerfile:
461619

0 commit comments

Comments
 (0)