Building a Docker Image
A Dockerfile packages your app and its dependencies into a portable image that runs anywhere.
Syntax
docker build -t myapp:1.0.0 .A container image bundles your app with everything it needs — runtime, libraries, config — so it runs identically on your laptop, in CI, and in production. You describe it in a Dockerfile.
Good image habits
- Multi-stage builds — compile in a big image, copy only the result into a tiny runtime image.
- Pin versions — use a specific base tag, not
latest. - Run as non-root — drop privileges for security.
- Keep images small so pulls and deploys are fast.
Example
# ---- build stage ----
FROM node:20-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# ---- runtime stage ----
FROM node:20-slim
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]When to use it
- A team packages their Python Flask API into a Docker image so it runs identically in development, staging, and production.
- A CI pipeline builds a Docker image on every pull request to verify the app compiles and its dependencies resolve correctly.
- An ops engineer uses a multi-stage Dockerfile to keep the final production image small by discarding build tools after compilation.
More examples
Minimal Node.js Dockerfile
Builds a lean Node.js image using the Alpine base, installs only production deps, and runs the server.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]Multi-stage build for smaller image
Uses a two-stage build so dev dependencies and source files are discarded and the final image only contains compiled output.
# Stage 1: build
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: run
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]Build and tag image with commit SHA
Builds the image and tags it with both the git commit SHA for traceability and 'latest' for convenience.
GIT_SHA=$(git rev-parse --short HEAD)
docker build \
--tag myapp:${GIT_SHA} \
--tag myapp:latest \
--file Dockerfile \
.
Discussion