Skip to main content

Docker Containerization Best Practices

Developer Tools HeStudy

What is Docker?

Docker is an open-source containerization platform that allows developers to package applications and their dependencies into lightweight, portable containers.

Basic Concepts

Image

An image is a template for containers, containing all files and configurations needed to run an application.

Container

A container is a running instance of an image, providing an isolated, lightweight runtime environment.

Dockerfile

A Dockerfile is a text file used to build Docker images.

Writing Efficient Dockerfiles

Basic Structure

# Use official base image
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application code
COPY . .

# Expose port
EXPOSE 3000

# Start command
CMD ["node", "server.js"]

Best Practices

1. Use Multi-Stage Builds

Reduce final image size by separating build and runtime environments.

# 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
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --only=production
CMD ["node", "dist/server.js"]

2. Optimize Layer Caching

Place instructions that change less frequently earlier, leveraging Docker’s layer caching mechanism.

# Good practice: Copy dependency files first
COPY package*.json ./
RUN npm ci

# Then copy application code (changes frequently)
COPY . .

3. Use .dockerignore

Create a .dockerignore file to exclude unnecessary files:

node_modules
npm-debug.log
.git
.env
*.md
.vscode

4. Reduce Image Size

  • Use lightweight base images like Alpine
  • Clean up unnecessary files
  • Combine RUN instructions
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

Docker Compose

For multi-container applications, use Docker Compose to simplify management.

docker-compose.yml Example

version: "3.8"

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://db:5432/myapp
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=myapp
    restart: unless-stopped

volumes:
  pgdata:

Common Commands

# Start all services
docker-compose up -d

# View logs
docker-compose logs -f

# Stop services
docker-compose down

# Rebuild
docker-compose build

Security Best Practices

1. Don’t Use root User

RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

USER nodejs

2. Scan for Vulnerabilities

# Use Trivy to scan images
docker run aquasec/trivy image myapp:latest

3. Use Secrets for Sensitive Information

Don’t hardcode passwords and keys in Dockerfile.

Performance Optimization

1. Resource Limits

services:
  web:
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          memory: 256M

2. Health Checks

HEALTHCHECK --interval=30s --timeout=3s \
  CMD node healthcheck.js || exit 1

3. Log Management

services:
  web:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Continuous Integration/Continuous Deployment

GitHub Actions Example

name: Build and Push Docker Image

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Build Docker image
        run: docker build -t myapp:latest .

      - name: Push to Registry
        run: |
          docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASS }}
          docker push myapp:latest

Common Troubleshooting

Container Won’t Start

# View container logs
docker logs <container-id>

# Enter container for debugging
docker exec -it <container-id> sh

Network Issues

# Check network configuration
docker network ls
docker network inspect bridge

Storage Space Issues

# Clean up unused resources
docker system prune -a

# Check disk usage
docker system df

Summary

Docker containerization provides a consistent, reliable way to deploy applications. Following best practices helps you build efficient and secure containerized applications.

References