Docs For AI
Containerization

Docker

Container platform for building, shipping, and running applications - Dockerfile, Compose, networking, and best practices

Docker

Docker is the industry-standard container platform that packages applications and their dependencies into lightweight, portable containers.

Core Concepts

ConceptDescription
ImageRead-only template containing application code, runtime, libraries, and configuration
ContainerRunning instance of an image with its own filesystem, networking, and process space
DockerfileText file with instructions to build an image
RegistryStorage and distribution service for images (Docker Hub, ECR, GCR, GHCR)
VolumePersistent storage mechanism that outlives container lifecycle
NetworkVirtual network for container-to-container communication

Dockerfile Best Practices

Multi-Stage Build (Node.js)

# Stage 1: Dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

# Stage 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable && pnpm build

# Stage 3: Production
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production

RUN addgroup --system --gid 1001 appgroup && \
    adduser --system --uid 1001 appuser

COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/package.json ./

USER appuser
EXPOSE 3000

CMD ["node", "dist/index.js"]

Multi-Stage Build (Go)

FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/server ./cmd/server

FROM scratch
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 8080
ENTRYPOINT ["/server"]

Layer Optimization

# Bad: Cache invalidated on every code change
COPY . .
RUN npm install

# Good: Dependencies cached separately
COPY package.json package-lock.json ./
RUN npm ci --production
COPY . .

Docker Compose

Full-Stack Application

# docker-compose.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: runner
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes --maxmemory 256mb
    volumes:
      - redis-data:/data
    ports:
      - "6379:6379"

volumes:
  pgdata:
  redis-data:

Networking

Network TypeDescriptionUse Case
bridgeDefault isolated networkContainer-to-container on same host
hostShares host network stackPerformance-critical, port conflicts possible
overlayMulti-host networkingDocker Swarm / multi-node clusters
noneNo networkingSecurity-sensitive isolated containers
# Custom networks in Compose
services:
  app:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend

  nginx:
    networks:
      - frontend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # No external access

Volume Management

services:
  app:
    volumes:
      # Named volume (managed by Docker)
      - app-data:/app/data

      # Bind mount (host directory)
      - ./config:/app/config:ro

      # tmpfs (in-memory, not persisted)
      - type: tmpfs
        target: /app/tmp
        tmpfs:
          size: 100m

volumes:
  app-data:
    driver: local

Security

PracticeDescription
Non-root userAlways run as non-root: USER appuser
Read-only filesystemUse read_only: true in Compose
Minimal base imagesUse alpine, slim, or distroless
No secrets in imagesUse runtime env vars or Docker secrets
Image scanningScan images with Trivy, Snyk, or Docker Scout
Pin versionsUse specific image tags, not latest
.dockerignoreExclude unnecessary files from build context

.dockerignore

node_modules
.git
.env
*.md
docker-compose*.yml
.github
coverage
.next
dist

Useful Commands

# Build
docker build -t myapp:latest .
docker build --target builder -t myapp:debug .

# Run
docker run -d --name myapp -p 3000:3000 --env-file .env myapp:latest
docker run --rm -it myapp:latest /bin/sh

# Inspect
docker logs -f --tail 100 myapp
docker exec -it myapp /bin/sh
docker stats myapp
docker inspect myapp

# Cleanup
docker system prune -a --volumes  # Remove all unused data
docker image prune -a              # Remove unused images
docker volume prune                # Remove unused volumes

# Compose
docker compose up -d
docker compose down -v
docker compose logs -f app
docker compose exec app /bin/sh
docker compose build --no-cache

Image Size Optimization

StrategyImpact
Multi-stage builds50-90% size reduction
Alpine base images~5MB vs ~100MB for full images
Distroless imagesMinimal attack surface, ~2MB base
.dockerignoreExclude dev files from build context
Minimize layersCombine RUN commands with &&
Remove cachesrm -rf /var/cache/apk/* after install

On this page