Agent Skills: Node.js Container Optimization

|

UncategorizedID: laurigates/claude-plugins/nodejs-containers

Install this agent skill to your local

pnpm dlx add-skill https://github.com/laurigates/claude-plugins/tree/HEAD/container-plugin/skills/nodejs-containers

Skill Files

Browse the full folder contents for nodejs-containers.

Download Skill

Loading file tree…

container-plugin/skills/nodejs-containers/SKILL.md

Skill Metadata

Name
nodejs-containers
Description
|

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:

# 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)

# 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

COPY package*.json ./
RUN npm ci --only=production
RUN npm cache clean --force

yarn

COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --production
RUN yarn cache clean

pnpm

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)

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.

Related Skills

  • container-development - General container patterns, multi-stage builds, security
  • go-containers - Go-specific container optimizations
  • python-containers - Python-specific container optimizations