A real walkthrough of shrinking bloated Docker images from 1.2GB to 240MB using multi-stage builds, Alpine, and dependency auditing.
Our main API image had grown to 1.2GB. Deploys were slow, registry costs were climbing, and cold starts on Kubernetes took 45 seconds. Here's exactly how we fixed it.
A quick docker history revealed the culprits:
We split the Dockerfile into build and runtime stages:
# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Runtime stage
FROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]
This alone dropped us from 1.2GB to 480MB.
We added a production-only install in the runtime stage:
FROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
Down to 310MB.
Running npx depcheck found 12 unused packages. We removed them and dropped another 70MB.
| Metric | Before | After |
|---|---|---|
| Image size | 1.2GB | 240MB |
| Pull time | 38s | 8s |
| Cold start | 45s | 12s |
| Registry cost | $180/mo | $40/mo |
npm ci --omit=dev to exclude dev dependenciesdocker scout or trivySmall images mean faster deploys, cheaper storage, and a smaller attack surface. There's no reason to ship your test framework to production.
Get the latest tutorials, guides, and insights on AI, DevOps, Cloud, and Infrastructure delivered directly to your inbox.
A real-world model fallback guide for customer-facing AI systems, covering how one team preserved response quality and support SLAs during a partial provider degradation.
A real cost audit uncovered idle load balancers, oversized RDS instances, and forgotten snapshots. Here's what we found and how we fixed each one.
Explore more articles in this category
How to write postmortems that lead to real improvements, not just documentation theater. Includes a template and real examples.
A practical artifact promotion guide for CI/CD teams that were tired of hearing 'it passed in staging' after production behaved differently because the release was rebuilt.
A Kubernetes blue-green deployment guide built around a real rollout failure, showing the guardrails that matter when traffic shifting, health checks, and rollback timing all interact.