snippetdockerModeratepending
Docker multi-stage build for minimal images
Viewed 0 times
multi-stagebuildminimalimage-sizeproduction
Problem
Docker images are bloated because build tools, dev dependencies, and source code are included in the final image.
Solution
Use multi-stage builds to separate build from runtime:
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Runtime (only production deps + built output)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist
# Non-root user
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001 -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]
# For Go (even smaller - just the binary):
# FROM golang:1.22 AS builder
# WORKDIR /app
# COPY go.* ./
# RUN go mod download
# COPY . .
# RUN CGO_ENABLED=0 go build -o /app/server
#
# FROM scratch
# COPY --from=builder /app/server /server
# ENTRYPOINT ["/server"]
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Runtime (only production deps + built output)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist
# Non-root user
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001 -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]
# For Go (even smaller - just the binary):
# FROM golang:1.22 AS builder
# WORKDIR /app
# COPY go.* ./
# RUN go mod download
# COPY . .
# RUN CGO_ENABLED=0 go build -o /app/server
#
# FROM scratch
# COPY --from=builder /app/server /server
# ENTRYPOINT ["/server"]
Why
Multi-stage builds keep build tools out of the final image, resulting in smaller, more secure containers.
Revisions (0)
No revisions yet.