Dockerfile Cheatsheet - Docker Image Build Reference
A Dockerfile authority for developers who want their images small, fast to finalize, and without leaked secrets. Beyond listing instructions, it explains why layer ordering and build cache matter, how multi-stage builds keep runtime images lean, and how ADD vs COPY, ENV vs ARG, USER and HEALTHCHECK change security and behavior. By the end you can write a Dockerfile that builds quickly and produces a minimal, production-safe image.
Base Instructions 7
FROM node:18-alpineSet the base image; alpine variants are smaller
FROM scratchEmpty base image for minimal static binaries
WORKDIR /appSet working directory, created automatically if missing
COPY package*.json ./Copy files into the container, supports globs
RUN npm ciExecute a command to build an image layer
EXPOSE 3000Document a container port (no actual mapping)
CMD ["node", "app.js"]Default start command, exec form is recommended
Env & Args 7
ENV NODE_ENV=productionSet an env var, also available at runtime
ENV PATH="/app/bin:$PATH"Append to PATH to make custom commands global
ARG VERSION=1.0Build-time argument, not present at runtime
ARG NPM_TOKENNo default; pass via --build-arg
LABEL maintainer="email@example.com"Add image metadata
USER appuserSwitch the runtime user to lower container privileges
HEALTHCHECK --interval=30s CMD curl -f http://localhost/ || exit 1Health check; marks unhealthy after consecutive failures
File Operations 5
COPY src/ ./src/Copy a directory into the container, target auto-created
COPY --chown=node:node . .Set file owner on copy to avoid root ownership
COPY --chmod=755 entrypoint.sh /entrypoint.shSet exec permission directly on copy (BuildKit)
ADD https://example.com/file.tar.gz /tmp/ADD can download URLs into the image
ADD file.tar.gz /app/Auto-extract local tar; prefer COPY for plain files
Multi-stage Build 5
FROM node:18 AS builderName a build stage for later reference
COPY --from=builder /app/dist ./distCopy artifacts from a build stage to the final image
COPY --from=nginx:alpine /etc/nginx/nginx.conf /etc/nginx/Copy files from an external image without pulling first
FROM golang:1.21 AS builderCompile stage of a Go multi-stage build
FROM alpine:3.18Final image uses a smaller base, down to a few MB
Entrypoint 5
CMD ["node", "app.js"]Default command, overridable by docker run args
ENTRYPOINT ["node"]Fixed entrypoint, not overridden by run args
ENTRYPOINT ["node"]
CMD ["app.js"]Combine: ENTRYPOINT sets program, CMD sets default args
SHELL ["/bin/bash", "-c"]Change default shell for RUN/CMD, common in Windows containers
ENTRYPOINT ["./docker-entrypoint.sh"]Custom entry script for init before the main process
Build Optimization 6
COPY package*.json ./Copy deps first then npm ci to leverage the cache layer
RUN npm ci && npm cache clean --forceMerge RUN to reduce layers and clean cache
RUN apk add --no-cache curlAlpine installs without caching indexes, smaller image
.dockerignoreExclude node_modules, .git and other unneeded build files
RUN --mount=type=cache,target=/root/.npm npm ciBuildKit cache mount reuses npm packages across builds
FROM node:18-alpinealpine base is ~5x smaller than the full image
Full Examples 3
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]Node multi-stage: build deps and compile, runtime keeps only artifacts and deps
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
CMD ["python", "main.py"]Python multi-stage: deps installed to --user, runtime copies only that dir
FROM golang:1.21 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server .
FROM alpine:3.18
COPY --from=builder /app/server /app/server
CMD ["/app/server"]Go multi-stage build: static binary keeps the image under 10 MB
Tips
- Each RUN/COPY/ADD instruction creates a new layer — merge RUN commands to reduce layer count.
- Multi-stage builds greatly shrink the final image, ideal for compiled languages like Go, Rust, Java.
- Use .dockerignore to exclude node_modules, .git, .env and other files not needed for the build.
- CMD vs ENTRYPOINT: CMD can be overridden by docker run arguments; ENTRYPOINT is fixed.
- Prefer the exec form ["cmd","arg"] over the shell form — it receives SIGTERM correctly and avoids stop timeouts.
- Don't pass secrets via --build-arg; they persist in the image build history. Use BuildKit secrets instead.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us