Skip to content

Dockerfile

First PublishedByAtif Alam

A Dockerfile is a text file of instructions used to build a Docker image. Each instruction creates a layer; order and caching matter for fast rebuilds.

InstructionPurpose
FROMBase image (e.g. FROM alpine:3.19 or FROM node:20-slim). Must be the first non-comment line.
RUNRun a command in the image (e.g. RUN apt-get update && apt-get install -y curl). Chain with && to reduce layers.
COPYCopy files from the build context into the image (e.g. COPY . /app). Prefer over ADD unless you need URL or tar extraction.
WORKDIRSet the working directory for subsequent instructions and for the running container (e.g. WORKDIR /app).
ENVSet environment variables (e.g. ENV NODE_ENV=production).
EXPOSEDocument which port the container listens on (e.g. EXPOSE 8080). Does not publish the port; use docker run -p to publish.
CMDDefault command when the container starts (e.g. CMD ["node", "server.js"]). Only one CMD; use exec form ["exec", "arg"].
ENTRYPOINTFixed executable; CMD becomes arguments. Use for “image as command” (e.g. ENTRYPOINT ["/app/entry.sh"]).
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV NODE_ENV=production
EXPOSE 8080
CMD ["node", "server.js"]

Use multiple FROM blocks to build in one stage and run in a smaller one. Build tools stay out of the final image:

# Build stage
FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
# Production stage
FROM node:20-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 8080
CMD ["node", "dist/server.js"]

A .dockerignore file (same syntax as .gitignore) excludes files from the build context. This speeds up builds and avoids copying secrets or node_modules:

node_modules
.git
.env
*.log
Dockerfile
.dockerignore
  • Use FROM, RUN, COPY, WORKDIR, ENV, EXPOSE, CMD (and ENTRYPOINT when the image is a single command).
  • Prefer multi-stage builds to keep the final image small and free of build tools.
  • Use .dockerignore to shrink context and avoid leaking sensitive or unneeded files.