RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /Production Local AI Deployment
  6. /Ch. 3
Production Local AI Deployment

03. Multi-Stage Builds

Chapter 3 of 24 · 20 min
KEY INSIGHT

Multi-stage builds separate compilation from execution, enabling minimal production images while preserving the build pipeline.

Multi-stage builds solve the problem of delivering production images that contain only runtime necessities while preserving build capabilities. The pattern uses multiple FROM statements, each beginning a new stage with independent base image.

Stage naming clarifies the build topology. The builder stage compiles source code. The runtime stage receives the compiled output. The final stage represents what gets shipped to production.

Common patterns exist for different language ecosystems. Go compiles to a static binary requiring only the operating system runtime. Python requires the interpreter and dependencies throughout execution. Rust produces native binaries with optional dynamic linking.

The COPY --from syntax transfers artifacts between stages. Copying specific paths rather than entire directories keeps final images focused. The destination path in the final stage should match expected runtime paths.

Build arguments enable cross-stage communication. SOURCE_STAGE_NAME and FINAL_STAGE_NAME expose stage indices for environments without named stage support.

# Syntax version required for advanced features
# syntax=docker/dockerfile:1.4

FROM golang:1.22-alpine AS builder
WORKDIR /src

# Dependencies first for layer caching
COPY go.mod go.sum ./
RUN go mod download

# Source after dependencies
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build \
    -ldflags="-w -s" \
    -o /bin/inference-server \
    ./cmd/server

# Runtime stage: minimal surface area
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /bin/inference-server /bin/inference-server

ENTRYPOINT ["/bin/inference-server"]

The scratch base image provides literally nothing beyond the kernel interface. Applications requiring TLS certificates, locale data, or DNS resolution need those files copied explicitly. Applications requiring static linking must compile without CGO.

Build secrets keep sensitive credentials out of image layers. dockerfile --secret passes secrets to builds without storing them in cache or layers. The RUN --mount=type=secret syntax provides temporary mounts that disappear after instruction completion.

EXERCISE

Convert an existing Dockerfile for a Node.js inference service into a multi-stage build. Identify build-time dependencies (TypeScript compiler, node-gyp build tools) versus runtime dependencies (Node interpreter, production packages). Verify the final image contains no compiler toolchains or source maps.

FROM node:20-alpine AS builder
WORKDIR /app

# Install all dependencies including dev dependencies
COPY package*.json ./
RUN npm ci

# Copy and build TypeScript
COPY . .
RUN npm run build

# Production stage: strip dev dependencies
FROM node:20-alpine AS runtime
WORKDIR /app

# Copy only production dependencies and built output
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./

USER node
EXPOSE 3000

CMD ["node", "dist/server.js"]
← Chapter 2
Dockerfile Optimization
Chapter 4 →
Docker Compose for AI Stack