Choosing a Base Image

The FROM instruction picks a base image; smaller bases like alpine and slim produce leaner, more secure images.

Every Dockerfile starts with a FROM instruction that chooses a base image. Your choice affects image size, security and how much you have to install yourself.

Common base image families

  • Full distrosubuntu, debian: familiar and complete, but larger.
  • Slim variantsdebian:12-slim, python:3.12-slim: trimmed-down versions with fewer packages.
  • Alpinealpine: tiny (a few MB) but uses musl libc, which can occasionally cause compatibility quirks.
  • Distroless — images with no shell or package manager, for minimal attack surface.
  • scratch — a completely empty image for statically compiled binaries.

Language-specific images

Official images like node, python and golang come with the runtime pre-installed, saving you setup work.

Example

Example · dockerfile
# A tiny, statically-linked Go binary on scratch
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app

FROM scratch
COPY --from=build /app /app
ENTRYPOINT ["/app"]

When to use it

  • A security team mandates alpine-based images for all microservices to minimise the attack surface by reducing the number of installed packages.
  • A developer switches from ubuntu to node:20-slim as the base image, cutting the final image size from 900 MB to 150 MB.
  • A platform team maintains a hardened internal base image that all product teams must inherit from to ensure compliance.

More examples

Compare common base image sizes

Pulls three Node.js base variants so you can compare their sizes and choose the leanest suitable option.

Example · bash
docker pull node:20
docker pull node:20-slim
docker pull node:20-alpine
docker images | grep node

Scratch base for static binary

Uses the scratch base (empty filesystem) so the final image contains only the static binary, nothing else.

Example · dockerfile
# Stage 1: build the Go binary
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app .

# Stage 2: zero-OS image
FROM scratch
COPY --from=builder /app /app
ENTRYPOINT ["/app"]

Use distroless base image

Distroless images contain only the runtime and its dependencies, with no shell or package manager to exploit.

Example · dockerfile
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["dist/index.js"]

Discussion

  • Be the first to comment on this lesson.