Skip to main content

nodejs-containers

Node.js container optimization — Alpine, multi-stage builds, node_modules caching, BuildKit mounts (900MB to ~100MB). Use when working with Node.js containers or optimizing image sizes.

معلومات المصدر

المستودع
laurigates/claude-plugins
آخر نشاط في المصدر
٢٤ سبتمبر ٢٠٢٦ في ١٠:٤٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥٩
التفرعات
٦

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
created
2026-01-15T00:00:00.000Z
modified
2026-09-24T00:00:00.000Z
reviewed
2026-01-15T00:00:00.000Z
name
nodejs-containers
description
Node.js container optimization — Alpine, multi-stage builds, node_modules caching, BuildKit mounts (900MB to ~100MB). Use when working with Node.js containers or optimizing image sizes.
user-invocable
false
allowed-tools
Bash, Read, Grep, Glob, Edit, Write, TodoWrite, WebSearch, WebFetch
# Node.js Container Optimization Expert knowledge for building optimized Node.js container images using Alpine variants, multi-stage builds, and Node.js-specific dependency management patterns. ## When to Use This Skill | Use this skill when... | Use `container-development` instead when... | |------------------------|---------------------------------------------| | Building Node.js-specific Dockerfiles | General multi-stage build patterns | | Optimizing Node.js image sizes | Language-agnostic container security | | Handling npm/yarn/pnpm in containers | Docker Compose configuration | | Dealing with native module builds | Non-Node.js container optimization | ## Core Expertise **Node.js Container Challenges**: - Large node_modules directories (100-500MB) - Full base images include build tools (~900MB) - Separate dev and production dependencies - Different package managers (npm, yarn, pnpm) - Native modules requiring build tools **Key Capabilities**: - Alpine-based images (~100MB vs ~900MB full) - Multi-stage builds separating build and runtime - BuildKit cache mounts for node_modules - Production-only dependency installation - Non-root user configuration ## Optimized Multi-Stage Pattern (Node Servers) The recommended pattern achieves ~100-150MB images: ```dockerfile # Dependencies stage - production only FROM node:20-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci --only=production # Build stage - includes devDependencies FROM node:20-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Runtime stage - minimal FROM node:20-alpine WORKDIR /app # Create non-root user RUN addgroup -g 1001 -S nodejs && \ adduser -u 1001 -S nodejs -G nodejs # Copy dependencies and built app COPY --from=deps --chown=nodejs:nodejs /app/node_modules ./node_modules COPY --from=build --chown=nodejs:nodejs /app/dist ./dist COPY --chown=nodejs:nodejs package.json ./ USER nodejs EXPOSE 3000 HEALTHCHECK --interval=30s CMD node healthcheck.js || exit 1 CMD ["node", "dist/server.js"] ``` ## BuildKit Cache Mounts (Fastest Builds) ```dockerfile # syntax=docker/dockerfile:1 FROM node:20-alpine AS build WORKDIR /app # Cache mount for npm cache RUN --mount=type=cache,target=/root/.npm \ --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=package-lock.json,target=package-lock.json \ npm ci COPY . . RUN npm run build FROM node:20-alpine WORKDIR /app COPY --from=build /app/dist ./dist USER node CMD ["node", "dist/server.js"] ``` **Build performance**: - First build: ~2-3 minutes - Subsequent builds (no package changes): ~10-20 seconds - Subsequent builds (package changes): ~30-60 seconds ## Package Manager Patterns ### npm ```dockerfile COPY package*.json ./ RUN npm ci --only=production RUN npm cache clean --force ``` ### yarn ```dockerfile COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile --production RUN yarn cache clean ``` ### pnpm ```dockerfile RUN npm install -g pnpm COPY package.json pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile --prod # pnpm creates smaller node_modules with hard links (20-30% smaller) ``` ## Next.js on Bun: build with Bun, run with Node Bun works for the dependency and build stages of a Next.js image, but the runtime stage that serves `.next/standalone` must be **Node.js**. The standalone output targets Node, and Bun does not resolve the React Server Components SSR modules it loads (`react-dom/server.edge`, `react-dom/server-rendering-stub`, `react-server-dom-webpack/client.edge`), so it fails at runtime with "Could not resolve" errors. ```dockerfile FROM oven/bun:1-debian AS deps # install FROM oven/bun:1-debian AS builder # next build FROM gcr.io/distroless/nodejs22-debian12 AS runner CMD ["server.js"] ``` ## Distroless runtime: no shell, so no `child_process` to CLI tools A distroless Node image contains Node and nothing else: no `/bin/sh`, `gzip`, `pg_dump`, or `psql`. Application code that shells out through `node:child_process` (`exec`, `execSync`, `spawn` of a CLI) works in local dev and fails only in production, with `spawn /bin/sh ENOENT`. Use Node built-ins or a library instead: | Shell tool | In-process replacement | |------------|------------------------| | `gzip` / `gunzip` | `node:zlib` (`gzipSync`, `createGzip`, `gunzipSync`) | | `cat`, `cp`, file writes | `node:fs` | | `pg_dump` / `psql` | export/import through the app's database client or ORM | The same constraint means ops scripts cannot be `kubectl exec`'d into the running app pod. Ship them in a separate image and run them as a Job. To stop the mistake before review, ban the import with a lint rule (for example Biome `noRestrictedImports` on `node:child_process` for server source). ## Performance Impact | Metric | Full Node (900MB) | Alpine (350MB) | Multi-Stage (100MB) | Improvement | |--------|-------------------|----------------|---------------------|-------------| | **Image Size** | 900MB | 350MB | 100MB | 89% reduction | | **Pull Time** | 3m 20s | 1m 10s | 25s | 87% faster | | **Build Time** | 4m 30s | 3m 15s | 2m 30s | 44% faster | | **Rebuild (cached)** | 2m 10s | 1m 30s | 15s | 88% faster | | **Memory Usage** | 512MB | 256MB | 180MB | 65% reduction | ## Security Impact | Image Type | Vulnerabilities | Size | Risk | |------------|-----------------|------|------| | **node:20 (Debian)** | 45-60 CVEs | 900MB | High | | **node:20-alpine** | 8-12 CVEs | 350MB | Medium | | **Multi-stage Alpine** | 4-8 CVEs | 100MB | Low | | **Distroless Node** | 2-4 CVEs | 120MB | Very Low | ## Agentic Optimizations | Context | Command | Purpose | |---------|---------|---------| | **Fast rebuild** | `DOCKER_BUILDKIT=1 docker build --target build .` | Build only build stage | | **Size check** | `docker images app --format "table {{.Repository}}\t{{.Size}}"` | Compare sizes | | **Layer analysis** | `docker history app:latest --human --no-trunc \| head -20` | Find large layers | | **Dependency audit** | `docker run --rm app npm audit --production` | Check vulnerabilities | | **Cache clear** | `docker builder prune --filter type=exec.cachemount` | Clear BuildKit cache | | **Test locally** | `docker run --rm -p 3000:3000 app` | Quick local test | ## Best Practices - Use Alpine variants for smaller images - Use `npm ci` not `npm install` (reproducible builds) - Separate dev and production dependencies - Run as non-root user - Use multi-stage builds for production - Layer package.json separately from source code - Add .dockerignore to exclude node_modules, tests For detailed examples, advanced patterns, and best practices, see [REFERENCE.md](REFERENCE.md). ## Related Skills - `container-development` - General container patterns, multi-stage builds, security - `go-containers` - Go-specific container optimizations - `python-containers` - Python-specific container optimizations
عرض على GitHub