Back to Blog
Tutorial7 min read2026-05-01

Docker Multi-Stage Builds: Smaller Images, Faster Deploys

Learn how Docker multi-stage builds dramatically reduce image size by separating build tooling from the final runtime image.

The Problem: Build Tools Don't Belong in Production

When you build a Go binary, a compiled Rust service, or a React app, you need compilers, build tools, and dev dependencies. But once the build is done, none of that is needed at runtime. Without multi-stage builds, all of it ends up baked into your production image — inflating its size by hundreds of megabytes.

Multi-stage builds solve this cleanly: use one image to build your artifact, then copy only the artifact into a minimal final image.

How Multi-Stage Builds Work

A multi-stage Dockerfile contains multiple FROM instructions. Each FROM starts a new stage. You can COPY --from= to pull files from previous stages. Only the last stage becomes your final image.

Example 1: Go Service

A Go application with dependencies can produce a completely static binary:

# Stage 1: Build
FROM golang:1.22-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o server .

# Stage 2: Runtime
FROM scratch

COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

EXPOSE 8080
CMD ["/server"]

Using FROM scratch means the final image contains only the binary and TLS certificates. A typical Go service image drops from ~300 MB to under 10 MB.

Example 2: React Frontend

# Stage 1: Build React app
FROM node:20-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Stage 2: Serve with nginx
FROM nginx:1.25-alpine

COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

The final image is a lean nginx image with your static files — Node.js and all dev dependencies are gone. Image size typically drops from ~900 MB to ~25 MB.

Example 3: Node.js with Compiled Native Modules

# Stage 1: Build (includes compilers for native modules)
FROM node:20-alpine AS builder

RUN apk add --no-cache python3 make g++

WORKDIR /app
COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Stage 2: Production runtime
FROM node:20-alpine

WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY package.json ./

USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

Build tools (python3, make, g++) are only in the builder stage.

Naming and Targeting Stages

Name stages with AS for readability and to enable partial builds:

# Build only up to the 'builder' stage (useful for CI caching)
docker build --target builder -t my-app:builder .

# Build the full image
docker build -t my-app:latest .

This is useful in CI pipelines where you want to cache the dependency installation stage separately.

Caching in CI with BuildKit

Enable BuildKit for better layer caching:

export DOCKER_BUILDKIT=1
docker build --cache-from my-app:builder -t my-app:latest .

Or with docker buildx:

docker buildx build   --cache-from type=registry,ref=my-app:cache   --cache-to type=registry,ref=my-app:cache,mode=max   -t my-app:latest .

Impact on Deploy Speed

Smaller images mean:

  • Faster pushes to registries
  • Faster pulls on deploy targets
  • Lower storage costs
  • Reduced attack surface (fewer packages = fewer CVEs)

A 10 MB image deploys in seconds. A 900 MB image can take minutes — and those minutes multiply across every deploy and every horizontal scale-out event.

Deploying Multi-Stage Builds on PandaStack

PandaStack's container deployment picks up your Dockerfile directly from GitHub and builds it in the platform — multi-stage builds are fully supported with no extra configuration.

npm install -g @pandastack/cli
panda deploy --type container --repo your-org/your-repo

PandaStack handles the build, registry push, and deployment. Visit [dashboard.pandastack.io](https://dashboard.pandastack.io) to monitor your deployments or check [docs.pandastack.io](https://docs.pandastack.io) for the full container deployment guide.

Ready to deploy?

Start free on PandaStack — no credit card required.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also