mediumDevOps EngineerTechnology
How do Docker layers work, and how would you optimize a Dockerfile for a Node.js application?
Posted 18/04/2026
by Mehedy Hasan Ador
Question Details
At a DevOps-focused company:
> "Our Docker images are 1.2GB and take 8 minutes to build. Builds are slow because every code change reinstalls all npm packages. How do we optimize this?"
> "Our Docker images are 1.2GB and take 8 minutes to build. Builds are slow because every code change reinstalls all npm packages. How do we optimize this?"
Suggested Solution
Docker Layers
EachRUN, COPY, ADD instruction creates a layer. Docker caches layers — if nothing changed, it reuses the cache.❌ BAD: Code changes invalidate npm install cache
FROM node:20
WORKDIR /app
COPY . . # Everything copied → layer changes on any file change
RUN npm install # Re-runs on every code change!
CMD ["node", "server.js"]
Image size: 1.2GB, Build time: 8min
✅ GOOD: Cache npm install separately
FROM node:20-alpine # Alpine = smaller base (180MB vs 1.1GB)
WORKDIR /app
Copy dependency files FIRST (changes rarely)
COPY package.json package-lock.json ./
RUN npm ci --only=production # Cached unless package.json changes
Copy source code LAST (changes frequently)
COPY . .
CMD ["node", "server.js"]
Image size: 250MB, Build time: 30s (with cache)
Multi-stage Build (production)
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 (smaller, no dev dependencies)
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/nodemodules ./nodemodules
EXPOSE 3000
CMD ["node", "dist/server.js"]
Final image: ~180MB (no build tools, no dev deps)
Optimization Summary
.dockerignorenpm ci instead of npm installnodemodules
.git
*.md
.env
.next