Source profileQuality 91/100

agents-inc/skills/src/skills/infra-ci-cd-docker/SKILL.md

infra-ci-cd-docker

Docker containerization patterns for Node.js/TypeScript development and production

Source repository stars
23
Declared platforms
0
Static risk flags
1
Last source update
2026-08-09
Source checked
2026-08-28

Decision brief

What it does: where it fits

Quick Guide: Docker with BuildKit for containerizing Node.js/TypeScript applications. Multi-stage builds for minimal production images (1GB to under 100MB). Docker Compose v2 for development environments. BuildKit cache mounts for 10x faster dependency installs. Non-root users,…

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/agents-inc/skills --skill "src/skills/infra-ci-cd-docker"
    Safe inspection promptEditorial

    Inspect the Agent Skill "infra-ci-cd-docker" from https://github.com/agents-inc/skills/blob/81d43a51211aca12c85dcc16085fa99014ec548e/src/skills/infra-ci-cd-docker/SKILL.md at commit 81d43a51211aca12c85dcc16085fa99014ec548e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Pattern 1: Multi-Stage Dockerfile for Node.js/TypeScript

      Multi-stage builds compile TypeScript in a builder stage, then copy only compiled JS and production dependencies into a minimal runtime image. This reduces images from 1GB+ to under 100MB.

      deps - Install production dependencies onlybuilder - Install all dependencies, compile TypeScriptrunner - Copy compiled output and production deps into minimal image
    2. 02

      Stage 1: Production dependencies

      FROM node:22-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN --mount=type=cache,target=/root/.npm \ npm ci --omit=dev --no-audit --no-fund

      FROM node:22-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN --mount=type=cache,target=/root/.npm \ npm ci --omit=dev --no-audit --no-fund
    3. 03

      Stage 2: Build TypeScript

      FROM node:22-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN --mount=type=cache,target=/root/.npm \ npm ci --no-audit --no-fund COPY tsconfig.json ./ COPY src/ ./src/ RUN npm run build

      FROM node:22-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN --mount=type=cache,target=/root/.npm \ npm ci --no-audit --no-fund COPY tsconfig.json ./ COPY src/ ./src/ RUN npm run build
    4. 04

      Stage 3: Production runtime

      FROM node:22-alpine AS runner WORKDIR /app RUN apk add --no-cache tini ENV NODEENV=production RUN addgroup --system --gid 1001 appgroup && \ adduser --system --uid 1001 --ingroup appgroup appuser COPY --from=deps --chown=appuser:appgroup /app/nodemodules ./nodemodules COPY --fro…

      FROM node:22-alpine AS runner WORKDIR /app RUN apk add --no-cache tini ENV NODEENV=production RUN addgroup --system --gid 1001 appgroup && \ adduser --system --uid 1001 --ingroup appgroup appuser COPY --from=deps --chow…
    5. 05

      CRITICAL: Before Using This Skill

      All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

      All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)(You MUST use multi-stage builds for production images - NEVER ship dev dependencies, TypeScript compiler, or source files in production)(You MUST run containers as non-root user - NEVER run production containers as root (default))

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 243

    The documentation includes network, browsing, or remote request actions.

    CMD ["node", "-e", "fetch('http://localhost:3000/health').then(r => { if (!r.ok) process.exit(1) }).catch(() => process.exit(1))"]

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score91/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars23SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    agents-inc/skills
    Skill path
    src/skills/infra-ci-cd-docker/SKILL.md
    Commit
    81d43a51211aca12c85dcc16085fa99014ec548e
    License
    MIT
    Collected
    2026-08-28
    Default branch
    main
    View the original SKILL.md

    Docker Containerization Patterns

    Quick Guide: Docker with BuildKit for containerizing Node.js/TypeScript applications. Multi-stage builds for minimal production images (1GB to under 100MB). Docker Compose v2 for development environments. BuildKit cache mounts for 10x faster dependency installs. Non-root users, health checks, and secret mounts for production security. Alpine for size, Debian slim for compatibility.


    <critical_requirements>

    CRITICAL: Before Using This Skill

    All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

    (You MUST use multi-stage builds for production images - NEVER ship dev dependencies, TypeScript compiler, or source files in production)

    (You MUST run containers as non-root user - NEVER run production containers as root (default))

    (You MUST use CMD ["node", "server.js"] (exec form) - NEVER use npm start or shell form as CMD)

    (You MUST use BuildKit secret mounts for sensitive data at build time - NEVER use ARG or ENV for secrets)

    (You MUST copy package.json/lockfile BEFORE source code - NEVER COPY . . before npm ci (breaks layer cache))

    </critical_requirements>


    Examples

    • Dockerfile Patterns - Multi-stage builds, Bun, monorepo, layer caching, .dockerignore, signal handling
    • Docker Compose - Development environments, networking, volumes, healthchecks
    • Production & CI/CD - Security hardening, secrets, CI/CD pipelines, vulnerability scanning
    • Quick Reference - Dockerfile instructions, CLI commands, base image comparison

    Auto-detection: Dockerfile, docker-compose, compose.yaml, Docker, container, multi-stage build, BuildKit, .dockerignore, Docker Compose, docker build, docker run, HEALTHCHECK, Docker Scout, docker init, containerize, container image, Docker network, Docker volume

    When to use:

    • Creating Dockerfiles for Node.js/TypeScript applications
    • Setting up multi-stage builds to minimize production image size
    • Configuring Docker Compose for local development environments
    • Optimizing Docker layer caching and BuildKit cache mounts
    • Implementing container security (non-root, secrets, read-only filesystem)
    • Setting up health checks for container orchestration
    • Building CI/CD pipelines that build and push Docker images
    • Teams needing consistent development environments across OS platforms
    • Microservice architectures requiring isolated services with dependencies

    When NOT to use:

    • Serverless deployments (AWS Lambda, Vercel Functions) that don't use containers
    • Static site hosting (Netlify, Vercel, Cloudflare Pages) with no server runtime
    • Simple scripts or CLI tools distributed via npm
    • Local development without containerization requirements
    • When added complexity outweighs the isolation benefit
    • Kubernetes-specific orchestration patterns (use a Kubernetes skill)

    Key patterns covered:

    • Multi-stage Dockerfile for Node.js/TypeScript (builder pattern)
    • Docker Compose v2 development environments
    • BuildKit cache mounts and layer optimization
    • Container security (non-root, secrets, capabilities, read-only)
    • Health checks for production containers
    • .dockerignore for build context optimization
    • Volume mounts (named volumes, bind mounts, tmpfs)
    • Docker networking (bridge, host, overlay)
    • CI/CD integration (GitHub Actions build-push)
    • Signal handling (tini for graceful shutdown)

    Philosophy

    Containers provide reproducible, isolated environments that eliminate "works on my machine" problems. Docker is the standard for packaging Node.js/TypeScript applications into portable, lightweight images.

    Core principles:

    1. Minimal production images - Ship only what the app needs to run (compiled JS, production deps, runtime)
    2. Layer cache optimization - Structure Dockerfiles so unchanged layers are reused, making rebuilds fast
    3. Security by default - Non-root users, no secrets in images, minimal attack surface
    4. Development parity - Docker Compose mirrors production topology locally

    Core Patterns

    Pattern 1: Multi-Stage Dockerfile for Node.js/TypeScript

    Multi-stage builds compile TypeScript in a builder stage, then copy only compiled JS and production dependencies into a minimal runtime image. This reduces images from 1GB+ to under 100MB.

    A production Dockerfile uses three stages:

    1. deps - Install production dependencies only
    2. builder - Install all dependencies, compile TypeScript
    3. runner - Copy compiled output and production deps into minimal image
    # Stage 1: Production dependencies
    FROM node:22-alpine AS deps
    WORKDIR /app
    COPY package.json package-lock.json ./
    RUN --mount=type=cache,target=/root/.npm \
        npm ci --omit=dev --no-audit --no-fund
    
    # Stage 2: Build TypeScript
    FROM node:22-alpine AS builder
    WORKDIR /app
    COPY package.json package-lock.json ./
    RUN --mount=type=cache,target=/root/.npm \
        npm ci --no-audit --no-fund
    COPY tsconfig.json ./
    COPY src/ ./src/
    RUN npm run build
    
    # Stage 3: Production runtime
    FROM node:22-alpine AS runner
    WORKDIR /app
    RUN apk add --no-cache tini
    ENV NODE_ENV=production
    RUN addgroup --system --gid 1001 appgroup && \
        adduser --system --uid 1001 --ingroup appgroup appuser
    COPY --from=deps --chown=appuser:appgroup /app/node_modules ./node_modules
    COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
    COPY --chown=appuser:appgroup package.json ./
    USER appuser
    EXPOSE 3000
    ENTRYPOINT ["/sbin/tini", "--"]
    CMD ["node", "dist/server.js"]
    

    Why good: Three-stage build separates concerns, BuildKit cache mount speeds up npm ci, non-root user, tini for signal handling, only production artifacts in final image

    See examples/core.md for complete Dockerfiles including Bun and monorepo variants.


    Pattern 2: Docker Compose for Development

    Docker Compose v2 defines multi-container development environments. Use compose.yaml (not docker-compose.yml) with the docker compose command (no hyphen).

    # compose.yaml
    services:
      app:
        build:
          context: .
          target: builder
        volumes:
          - .:/app:cached
          - /app/node_modules
        depends_on:
          db:
            condition: service_healthy
      db:
        image: postgres:17-alpine
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U dev"]
          interval: 10s
          timeout: 5s
          retries: 5
          start_period: 30s
        volumes:
          - pgdata:/var/lib/postgresql/data
    volumes:
      pgdata:
    

    Why good: Health checks on dependencies with condition: service_healthy, bind mount with :cached for macOS perf, anonymous volume protects node_modules, named volume for database persistence

    See examples/compose.md for full development environments with Redis, networking, and volume patterns.


    Pattern 3: BuildKit Cache Mounts

    BuildKit (default since Docker Engine 23+) provides cache mounts that persist package manager caches across builds, reducing install times by 10x or more.

    # npm
    RUN --mount=type=cache,target=/root/.npm \
        npm ci --no-audit --no-fund
    
    # pnpm
    RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
        pnpm install --frozen-lockfile
    

    Layer ordering rules: Pin base image versions > Copy dependency manifests > Install dependencies > Copy source code > Build/compile. This maximizes cache hits.

    See examples/core.md for cache mount patterns for npm, Bun, pnpm, and apt.


    Pattern 4: Container Security

    Non-Root User

    RUN addgroup --system --gid 1001 appgroup && \
        adduser --system --uid 1001 --ingroup appgroup appuser
    COPY --chown=appuser:appgroup --from=builder /app/dist ./dist
    USER appuser
    

    Secret Mounts (Build Time)

    # Secret is ephemeral - never persisted in image layers
    RUN --mount=type=secret,id=npm_token,env=NPM_TOKEN \
        npm ci --no-audit --no-fund
    # Build: docker build --secret id=npm_token,env=NPM_TOKEN .
    

    Runtime Hardening

    services:
      app:
        read_only: true
        tmpfs: [/tmp]
        security_opt: [no-new-privileges:true]
        cap_drop: [ALL]
    

    See examples/production.md for complete production compose, secrets management, and CI/CD pipelines.


    Pattern 5: Health Checks

    Health checks enable orchestrators to detect unresponsive containers and restart them automatically.

    HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=30s \
        CMD ["node", "-e", "fetch('http://localhost:3000/health').then(r => { if (!r.ok) process.exit(1) }).catch(() => process.exit(1))"]
    

    Why good: Uses Node.js built-in fetch (no curl needed in Alpine), start-period allows app startup, checks dedicated health endpoint not just root path

    See examples/production.md for health check endpoint implementation and Compose healthcheck patterns.


    Pattern 6: .dockerignore

    node_modules
    dist
    .git
    .env
    .env.*
    !.env.example
    Dockerfile*
    compose.yaml
    __tests__
    *.test.ts
    coverage
    .github
    

    Why good: Excludes node_modules (reinstalled deterministically), .env files (prevents secret leaks), .git (invalidates cache), keeps build context small

    See examples/core.md for a comprehensive .dockerignore file.


    Pattern 7: Signal Handling and Graceful Shutdown

    Node.js as PID 1 does not handle SIGTERM/SIGINT correctly. Use tini as init system.

    RUN apk add --no-cache tini
    ENTRYPOINT ["/sbin/tini", "--"]
    CMD ["node", "dist/server.js"]
    

    Why good: Tini forwards signals to node process, handles zombie process reaping, ensures graceful shutdown on docker stop

    See examples/core.md for complete TypeScript graceful shutdown implementation.


    Performance Optimization

    Image Size Reduction

    TechniqueImpact
    Multi-stage builds1GB to under 100MB (90%+ reduction)
    Alpine base image135MB vs 1GB (full) vs 200MB (slim)
    npm ci --omit=devRemoves dev dependencies from production
    .dockerignoreSmaller build context, faster sends

    Build Speed Optimization

    TechniqueImpact
    BuildKit cache mounts10x faster dependency installs
    Layer ordering (deps before source)Cache hit on source-only changes
    .dockerignore excluding node_modulesPrevents sending GBs to daemon
    --no-audit --no-fund flagsSkip unnecessary npm checks
    Parallel multi-stage buildsBuildKit builds independent stages concurrently

    CI/CD Build Cache

    # GitHub Actions - Cache Docker layers
    - uses: docker/setup-buildx-action@v3
    - uses: docker/build-push-action@v7
      with:
        cache-from: type=gha
        cache-to: type=gha,mode=max
    

    Why good: GitHub Actions cache (type=gha) persists layers across CI runs, mode=max caches all layers (not just final)

    See examples/production.md for complete CI/CD pipeline examples.


    <decision_framework>

    Decision Framework

    Base Image Selection

    Which base image?
      |
      +-- Need smallest image? --> Alpine (node:22-alpine, ~135MB)
      |     +-- musl libc compatibility issues? --> Use Debian slim instead
      |
      +-- Need maximum compatibility? --> Debian slim (node:22-slim, ~200MB)
      |     +-- Native extensions work out of the box
      |
      +-- Need debugging tools? --> Full image (node:22, ~1GB)
      |     +-- Development only, never for production
      |
      +-- Maximum security? --> Distroless (gcr.io/distroless/nodejs22-debian12)
            +-- No shell, no package manager, smallest attack surface
    

    Compose vs Dockerfile Targets

    How to manage dev vs prod?
      |
      +-- Multi-stage Dockerfile with targets
      |     +-- `docker compose build --target builder` for dev
      |     +-- Final stage for production
      |
      +-- Separate compose files
            +-- compose.yaml (base)
            +-- compose.override.yaml (dev - auto-loaded)
            +-- compose.prod.yaml (production)
    

    Volume Strategy

    What data needs to persist?
      |
      +-- Source code (dev hot reload) --> Bind mount with :cached
      +-- Database files --> Named volume
      +-- Temporary/cache data --> tmpfs
      +-- Secrets at runtime --> Docker secrets or tmpfs
      +-- node_modules in dev --> Anonymous volume (protect from host)
    

    </decision_framework>


    Integration Guide

    Docker ecosystem tools:

    • Docker Scout: docker scout cves for vulnerability scanning in CLI and CI
    • BuildKit: Default build engine since Docker Engine 23+, enables cache mounts, secret mounts, multi-platform builds

    CI/CD integration:

    Docker images integrate with any CI/CD pipeline. See examples/production.md for build-push patterns and vulnerability scanning workflows.

    Container orchestration:

    Production images work with any container orchestrator. Health checks (HEALTHCHECK instruction) and non-root users are universally required regardless of platform.

    Replaces:

    • VM-based development environments (Docker Compose provides lighter isolation)
    • Manual server provisioning (Dockerfiles codify environment setup)
    • Node version managers in containers (Dockerfile pins exact Node version via base image tag)

    <red_flags>

    RED FLAGS

    High Priority Issues:

    • Running production containers as root (default behavior - always add USER directive)
    • Secrets in ARG/ENV/COPY (persist in image layers - use --mount=type=secret)
    • Single-stage builds shipping dev dependencies and source code to production
    • Using npm start as CMD (npm swallows SIGTERM - use CMD ["node", "dist/server.js"])
    • No .dockerignore file (node_modules sent to daemon, secrets leaked into image)
    • Using :latest tag for base images (non-deterministic builds)

    Medium Priority Issues:

    • COPY . . before npm ci (any file change invalidates dependency cache)
    • No health check defined (orchestrator cannot detect unresponsive containers)
    • docker-compose.yml with version: key (deprecated - use compose.yaml without version)
    • depends_on without condition: service_healthy (container starts before dependency is ready)
    • Using npm install instead of npm ci in Dockerfile (non-deterministic, slower)

    Common Mistakes:

    • Forgetting anonymous volume for node_modules in dev (/app/node_modules) causing host to overwrite container's modules
    • Not using :cached on bind mounts on macOS (significant performance impact)
    • Installing build tools (gcc, make, python) in the final stage instead of the builder stage
    • Exposing database ports to host in production Compose (only needed for dev)

    Gotchas & Edge Cases:

    • Alpine uses musl libc - some npm packages with native C bindings (bcrypt, sharp, canvas) may fail; use npm rebuild or switch to Debian slim
    • Node.js fetch() is available since Node 18+ (no need for curl in health checks on Alpine)
    • BuildKit cache mounts require # syntax=docker/dockerfile:1 or Docker Engine 23+ with BuildKit enabled by default
    • docker compose down -v removes named volumes (data loss) - use docker compose down without -v to preserve data
    • Docker Desktop on macOS/Windows has different file system performance than Linux - bind mounts are slower
    • COPY --chown is more efficient than COPY + RUN chown (one layer vs two)
    • tini must be installed explicitly on Alpine (apk add --no-cache tini) - it is NOT included by default in node:alpine images
    • The node_modules/.cache directory can grow large in development - add it to .dockerignore

    </red_flags>


    <critical_reminders>

    CRITICAL REMINDERS

    All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

    (You MUST use multi-stage builds for production images - NEVER ship dev dependencies, TypeScript compiler, or source files in production)

    (You MUST run containers as non-root user - NEVER run production containers as root (default))

    (You MUST use CMD ["node", "server.js"] (exec form) - NEVER use npm start or shell form as CMD)

    (You MUST use BuildKit secret mounts for sensitive data at build time - NEVER use ARG or ENV for secrets)

    (You MUST copy package.json/lockfile BEFORE source code - NEVER COPY . . before npm ci (breaks layer cache))

    Failure to follow these rules will result in bloated images (1GB+), security vulnerabilities (root access, leaked secrets), broken graceful shutdown (lost requests on deploy), and slow CI builds (no layer caching).

    </critical_reminders>

    Frequently asked questions

    What to verify before installation and use

    What does the infra-ci-cd-docker source document cover?

    Quick Guide: Docker with BuildKit for containerizing Node.js/TypeScript applications. Multi-stage builds for minimal production images (1GB to under 100MB). Docker Compose v2 for development environments. BuildKit cache mounts for 10x faster dependency installs. Non-root users,…

    How do I install infra-ci-cd-docker?

    The source record exposes this install command: npx skills add https://github.com/agents-inc/skills --skill "src/skills/infra-ci-cd-docker". Inspect the command and pinned source before running it.

    Which permission-related actions were detected?

    Static rules flagged network in the source; the page lists the matching lines and excerpts.