Skillversitas

Docker Image Layering

Each instruction in a Dockerfile creates a new layer. Understanding layering is important for optimization.

Layer Structure

+-------------------+
|   COPY . .        |  <- Layer 4 (2 MB)
+-------------------+
|   RUN npm install |  <- Layer 3 (200 MB)
+-------------------+
|   COPY pkg.json   |  <- Layer 2 (1 KB)
+-------------------+
|   FROM node:18    |  <- Layer 1 (300 MB)
+-------------------+

Total: 502 MB

Viewing Layers

# View image layers
docker history nginx:latest

# View layer details
docker inspect nginx:latest

Caching Mechanism

# Layer 1: Base image (cached)
FROM node:18-alpine

# Layer 2: Copy dependencies (cached if unchanged)
COPY package*.json ./

# Layer 3: Install dependencies (cached if package.json is unchanged)
RUN npm ci --only=production

# Layer 4: Copy source (always rebuilt if there are changes)
COPY . .

Layer Optimization

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

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

Multi-Stage Build

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

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

Use Case

# Optimized Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app

# Layer for dependencies
COPY package*.json ./
RUN npm ci --only=production

# Layer for source code
COPY . .

# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app .
EXPOSE 3000
CMD ["node", "server.js"]

Everyday Use Case

Case: Build time is too long.

# Check 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 .

Best Practices

  1. Order instructions correctly: Put what rarely changes on top
  2. Combine RUN commands: Reduce the number of layers
  3. Use multi-stage builds: For smaller images
  4. Use .dockerignore: Avoid copying unneeded files
  5. Cache dependencies: Copy package*.json before the source

Conclusion

Layering is the foundation of Docker images. With the right optimization, build time and image size can be significantly reduced.