Docker Compose — Multi-Stage in Compose
Multi-stage Dockerfiles produce small, secure production images. Compose makes it easy to target different stages for different environments.
Multi-Stage Dockerfile
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]
# Stage 3: Development
FROM node:20-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
Targeting Stages in Compose
services:
api:
build:
context: ./api
target: production # Use the 'production' stage
ports:
- "3000:3000"
Multiple Profiles for Different Stages
services:
api-prod:
build:
context: ./api
target: production
ports:
- "3000:3000"
profiles: ["prod"]
api-dev:
build:
context: ./api
target: development
ports:
- "3000:3000"
volumes:
- ./api:/app
profiles: ["dev"]
docker compose --profile dev up # Development stage
docker compose --profile prod up # Production stage
Size Comparison
┌──────────────────────────────────────┐
│ Without multi-stage: │
│ node:20 + sources + devDeps │
│ → ~900 MB │
│ │
│ With multi-stage (production): │
│ node:20-alpine + dist + prodDeps │
│ → ~150 MB │
└──────────────────────────────────────┘
Override Target for Development
compose.yml (production default):
services:
api:
build:
context: ./api
target: production
compose.override.yml (development override):
services:
api:
build:
target: development
volumes:
- ./api:/app
Summary
| Feature | Detail |
|---|---|
target: |
Select Dockerfile stage |
| Production | Final stage, minimal image |
| Development | Full tools, source mounted |
| Override | compose.override.yml for dev |
| Profiles | Different services per environment |
Quick Reference
| Item | Detail |
|---|---|
| target: | Select a Dockerfile stage |
| AS builder | Named stages in Dockerfile |
| COPY –from=builder | Copy artifacts between stages |
| Production | Minimal final stage |
| Development | Full tooling stage |
| Override | compose.override.yml for dev target |