Skillversitas

Docker Build Optimization

Optimize Docker builds to reduce build time and image size.

1. Layer Caching

# Good: Copy dependencies first
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

# Bad: Copy everything then install
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm ci --only=production

2. Multi-Stage Build

# Stage 1: Build
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

3. Use BuildKit

# Enable BuildKit
DOCKER_BUILDKIT=1 docker build -t myapp .

# Or in daemon.json
# { "features": { "buildkit": true } }

4. Effective .dockerignore

node_modules
npm-debug.log
.git
.gitignore
.env
.env.local
*.md
docker-compose*.yml
Dockerfile*
.dockerignore
coverage
.nyc_output
dist
build

5. Reduce the Number of Layers

# Bad
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y wget
RUN apt-get clean

# Good
RUN apt-get update && \
    apt-get install -y curl wget && \
    rm -rf /var/lib/apt/lists/*

Use Case: Build Optimization

# Before: 250MB, 15-second build
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

# After: 120MB, 8-second build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]

Everyday Use Case

Case: Build time is too long.

# View the layers that changed
docker history myapp:latest

# Build with cache
docker build -t myapp:latest .

# Build without cache
docker build --no-cache -t myapp:latest .

# View the build cache
docker builder du

Cache Invalidation

# Delete the build cache
docker builder prune

# Delete all caches
docker builder prune -a

# View cache size
docker system df -v

Best Practices

  1. Use .dockerignore: Avoid copying unneeded files
  2. Order instructions correctly: Put what rarely changes on top
  3. Use BuildKit: For parallel builds
  4. Multi-stage builds: For smaller images
  5. Cache dependencies: Copy package*.json first

Conclusion

Build optimization reduces development time and image size. Use layer caching, multi-stage builds, and .dockerignore for optimal results.