
Dockerfile Basics
Scaffold a multi-stage production Dockerfile for Node apps and lint it with Hadolint before you containerize and deploy.
Overview
dockerfile-basics is an agent skill most often used in Ship (also Build/backend) that provides a production-ready multi-stage Node Dockerfile template and Hadolint linting workflow.
Install
npx skills add https://github.com/pluginagentmarketplace/custom-plugin-docker --skill dockerfile-basicsWhat is this skill?
- Multi-stage Dockerfile template: deps, builder, and runner with node:20-alpine
- Security defaults: non-root nextjs user (uid 1001), NODE_ENV=production, pinned base image
- Best-practice checklist: layer ordering, .dockerignore, combined RUN, alpine/slim images
- Hadolint-based dockerfile-lint.sh with Docker fallback when hadolint is not installed
- Performance guidance: build-cache-friendly COPY order and multi-stage separation
- 3-stage Dockerfile pattern: deps, builder, runner
- dockerfile-lint.sh supports local Hadolint or hadolint/hadolint Docker image
Adoption & trust: 1 installs on skills.sh; 2 GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
What problem does it solve?
You can run the app locally but your Dockerfile is missing multi-stage builds, a non-root user, and lint checks before push.
Who is it for?
Solo builders containerizing a Node 20 app who want a vetted starter Dockerfile and quick lint loop.
Skip if: Pure serverless deploys with no containers, or advanced polyglot monorepos needing bespoke base images without adaptation.
When should I use this skill?
You need to learn Dockerfile fundamentals or apply the production-ready Node template and lint script before building container images.
What do I get? / Deliverables
You produce a hardened, cache-friendly Dockerfile and can run Hadolint feedback before building the production image.
- Production-oriented Dockerfile
- Hadolint lint results for the Dockerfile
- Applied layer and security best-practice notes
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Container images are the canonical Ship concern: you finalize how the app runs in production right before or during launch, even though authoring happens during Build. Launch is the shelf because the skill optimizes production images (non-root user, pinned Node 20 alpine, exposed port, CMD) for go-live—not local dev-only Docker.
Where it fits
Add a first Dockerfile to a Node API repo using the deps/builder/runner pattern before wiring docker compose locally.
Finalize EXPOSE, CMD, and non-root USER before pushing the image to your registry for production.
Run dockerfile-lint.sh with Hadolint to catch missing pins and risky RUN patterns pre-release.
Refactor an bloated single-stage image into multi-stage alpine to cut size and attack surface on an existing service.
How it compares
Template-plus-linter skill for Dockerfiles—not a full CI/CD pipeline or Kubernetes deploy package.
Common Questions / FAQ
Who is dockerfile-basics for?
Indie and solo developers using AI coding agents who are dockerizing a Node app for the first production deploy.
When should I use dockerfile-basics?
In Ship/launch when preparing registry images; in Build/backend when you first add Docker to the repo; before perf or security review if images grew ad hoc.
Is dockerfile-basics safe to install?
It suggests non-root users and linting—review the Security Audits panel on this page and scan images in your registry CI before production.
SKILL.md
READMESKILL.md - Dockerfile Basics
# Production-Ready Dockerfile Template # Version: 1.0.0 FROM node:20-alpine AS base # Set working directory WORKDIR /app # Install dependencies only when needed FROM base AS deps COPY package*.json ./ RUN npm ci --only=production # Build the application FROM base AS builder COPY --from=deps /app/node_modules ./node_modules COPY . . RUN npm run build # Production image FROM base AS runner ENV NODE_ENV=production # Create non-root user RUN addgroup -g 1001 -S nodejs && \ adduser -S nextjs -u 1001 # Copy built assets COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist COPY --from=deps --chown=nextjs:nodejs /app/node_modules ./node_modules USER nextjs EXPOSE 3000 CMD ["node", "dist/index.js"] # Dockerfile Best Practices ## Layer Optimization - Combine RUN commands with && - Put frequently changing commands last - Use .dockerignore ## Security - Use non-root USER - Scan for vulnerabilities - Pin versions ## Performance - Use multi-stage builds - Leverage build cache - Use alpine/slim images #!/bin/bash # Dockerfile Linter using Hadolint # Usage: ./dockerfile-lint.sh [Dockerfile] DOCKERFILE=${1:-Dockerfile} if ! command -v hadolint &> /dev/null; then echo "Running hadolint via Docker..." docker run --rm -i hadolint/hadolint < "$DOCKERFILE" else hadolint "$DOCKERFILE" fi --- name: dockerfile-basics description: Learn Dockerfile fundamentals and best practices for building production-ready container images sasmp_version: "1.3.0" bonded_agent: 01-docker-fundamentals bond_type: PRIMARY_BOND --- # Dockerfile Basics Skill Master Dockerfile fundamentals and 2024-2025 best practices for building secure, optimized container images. ## Purpose Provide comprehensive guidance on Dockerfile syntax, instruction ordering, layer optimization, and security best practices. ## Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | base_image | string | No | - | Base image to use | | language | string | No | - | Programming language (node/python/go/java) | | optimize | boolean | No | true | Apply optimization recommendations | ## Core Instructions ### Instruction Reference | Instruction | Purpose | Example | |-------------|---------|---------| | FROM | Base image | `FROM node:20-alpine` | | WORKDIR | Set working directory | `WORKDIR /app` | | COPY | Copy files | `COPY package*.json ./` | | RUN | Execute command | `RUN npm ci` | | ENV | Set environment | `ENV NODE_ENV=production` | | EXPOSE | Document port | `EXPOSE 3000` | | USER | Set user | `USER appuser` | | CMD | Default command | `CMD ["node", "app.js"]` | | ENTRYPOINT | Fixed command | `ENTRYPOINT ["./start.sh"]` | | HEALTHCHECK | Health check | `HEALTHCHECK CMD curl -f http://localhost/` | ### Layer Optimization Order ```dockerfile # 1. Base image (most stable) FROM node:20-alpine # 2. System dependencies RUN apk add --no-cache curl # 3. Create user (security) RUN addgroup -g 1001 app && adduser -u 1001 -G app -D app # 4. Set working directory WORKDIR /app # 5. Copy dependency files (cache layer) COPY package*.json ./ # 6. Install dependencies RUN npm ci --only=production # 7. Copy application code (most volatile) COPY --chown=app:app . . # 8. Switch to non-root user USER app # 9. Health check HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:3000/health || exit 1 # 10. Default command CMD ["node", "server.js"] ``` ## Best Practices (2024-2025) ### Security Essentials ```dockerfile # Always use specific version tags FROM node:20.10-alpine # Good # FROM node:latest # Bad # Run as non-root user USER nonroot # Use multi-stage builds FROM node:20 AS builder # ... build steps ... FROM node:20-alpine AS runtime COPY --from=builder /app/dist ./ ``` ### Optimization Techniques ```dockerfile # Combine RUN commands RUN apt-get update && \ apt-get install -y --no-install-recommends curl && \ rm -rf /var/lib/apt/lists/* # Use .dockerignore #