stackademic

The leading education platform for anyone with an interest in software development.

Best Practices

Practical habits for smaller, faster, and more secure Docker images

Overview

Following a few best practices keeps your images small, your builds fast, and your containers secure. Small images pull faster and have a smaller attack surface, while good layer ordering makes rebuilds nearly instant. These habits pay off as soon as you share images with a team or deploy them.

Syntax / Usage

Two of the highest-impact techniques are multi-stage builds (to drop build tooling from the final image) and a .dockerignore file (to keep junk out of the build context).

# Stage 1: build
FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: slim runtime image
FROM node:20-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]

Examples

A .dockerignore keeps large or sensitive files out of the build context:

node_modules
.git
.env
*.log

Pin base image versions instead of relying on latest for reproducible builds:

FROM python:3.12.4-slim

Common Mistakes

  • Using latest tags, which makes builds non-reproducible
  • Copying source before installing dependencies, breaking the layer cache
  • Running containers as root instead of a dedicated non-root USER
  • Baking secrets into image layers where they remain recoverable
  • Shipping build tools and dev dependencies in the final production image

See Also

docker-dockerfile docker-images-and-containers docker-compose