Docker Cheatsheet
Dockerfile
Use this Docker reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Instruction Reference
| Instruction | Purpose | Example |
|---|---|---|
FROM | Base image (must be first) | FROM node:22-alpine |
RUN | Execute command in a new layer | RUN npm ci --omit=dev |
CMD | Default command (overridable) | CMD ["node", "server.js"] |
ENTRYPOINT | Fixed executable | ENTRYPOINT ["python", "app.py"] |
COPY | Copy files from build context | COPY package*.json ./ |
ADD | Like COPY + auto-extract tarballs, URL fetch | ADD archive.tar.gz /data/ |
WORKDIR | Set working directory | WORKDIR /app |
ENV | Set environment variable | ENV NODE_ENV=production |
ARG | Build-time variable | ARG VERSION=1.0 |
EXPOSE | Document listening port | EXPOSE 8080 |
VOLUME | Declare a mount point | VOLUME ["/data"] |
USER | Switch to user/UID | USER node |
LABEL | Key-value metadata | LABEL version="1.0" |
HEALTHCHECK | Container health probe | see below |
SHELL | Override default shell | SHELL ["/bin/bash", "-o", "pipefail", "-c"] |
STOPSIGNAL | Signal sent on docker stop | STOPSIGNAL SIGTERM |
ONBUILD | Trigger in child images | ONBUILD COPY . /app |
Minimal Node.js Example
FROM node:22-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev COPY . . EXPOSE 3000 USER node CMD ["node", "server.js"]
Minimal Python Example
FROM python:3.13-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 USER nobody CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD vs ENTRYPOINT
# CMD alone — all arguments overridable at runtime CMD ["node", "server.js"] # ENTRYPOINT alone — fixed binary, no default args ENTRYPOINT ["python", "app.py"] # Together (recommended) — ENTRYPOINT is the executable, CMD are default args ENTRYPOINT ["nginx", "-g"] CMD ["daemon off;"] # docker run img -> nginx -g "daemon off;" # docker run img daemon on; -> nginx -g "daemon on;"
Always use exec form (
["cmd", "arg"]) for CMD/ENTRYPOINT so signals are delivered directly to the process, not a shell.
ARG and ENV
ARG NODE_VERSION=22 # build-time only; not available at runtime ENV PORT=3000 # available at runtime too ENV APP_HOME=/app \ LOG_LEVEL=info # Use ARG to parameterise the base image ARG BASE=node:22-alpine FROM ${BASE}
docker build --build-arg NODE_VERSION=20 .HEALTHCHECK
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD wget -qO- http://localhost:3000/health || exit 1
.dockerignore
node_modules .git .env* dist *.log **/*.test.*
.dockerignorepatterns follow.gitignoresyntax. Always excludenode_modules,.git, and secrets before the firstCOPY . ..
Layer Caching Best Practices
# Copy dependency manifests FIRST so installs are cached
COPY package*.json ./
RUN npm ci
# Source changes only invalidate layers from here down
COPY . .SHELL for Pipefail Safety
SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN curl -fsSL https://example.com | bash # fails if curl fails
Labels (OCI standard)
LABEL org.opencontainers.image.source="https://github.com/org/repo" \ org.opencontainers.image.version="1.2.3" \ org.opencontainers.image.licenses="MIT"