Docker - Containerization Platform

Overview

Docker is our primary containerization platform, enabling consistent deployment across development, staging, and production environments. We use Docker to package applications with their dependencies, ensuring reliability and portability.

Why Docker?

  • ๐Ÿ“ฆ Consistency: Same environment across all stages
  • ๐Ÿš€ Portability: Run anywhere Docker is supported
  • ๐Ÿ”ง Isolation: Applications run in isolated containers
  • ๐Ÿ“ˆ Scalability: Easy horizontal scaling
  • ๐Ÿ”„ Version Control: Image versioning and rollbacks

Docker at Tresor

Use Cases

  • Application deployment
  • Microservices architecture
  • Development environments
  • CI/CD pipelines
  • Database containers for development

Container Registry

  • AWS ECR for production images
  • Docker Hub for public images
  • GitLab Registry for internal images

Getting Started

Installation

# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# Add user to docker group
sudo usermod -aG docker $USER

Basic Commands

# Build image
docker build -t myapp:latest .

# Run container
docker run -d -p 3000:3000 --name myapp myapp:latest

# View logs
docker logs -f myapp

# Execute command in container
docker exec -it myapp bash

Best Practices

Dockerfile Optimization

Multi-stage Builds

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

# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/index.js"]

Layer Caching

# Good: Dependencies cached separately
COPY package*.json ./
RUN npm ci
COPY . .

# Bad: Any code change invalidates npm install
COPY . .
RUN npm ci

Security Best Practices

# Use specific versions
FROM node:18.17.1-alpine

# Run as non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs

# Copy with correct permissions
COPY --chown=nodejs:nodejs . .

Docker Compose

Development Environment

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
    volumes:
      - .:/app
      - /app/node_modules
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:

Production Considerations

version: '3.8'

services:
  app:
    image: myapp:${VERSION:-latest}
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Common Patterns

Node.js Application

FROM node:18-alpine

# Install dumb-init for proper signal handling
RUN apk add --no-cache dumb-init

WORKDIR /app

# Copy and install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy application
COPY . .

# Create non-root user
USER node

EXPOSE 3000

ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "server.js"]

Python Application

FROM python:3.11-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY . .

# Run as non-root
RUN useradd -m -u 1001 python
USER python

EXPOSE 8000

CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

Static Website

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

# Serve stage
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Docker in CI/CD

GitHub Actions

- name: Build and push Docker image
  uses: docker/build-push-action@v4
  with:
    context: .
    push: true
    tags: |
      user/app:latest
      user/app:${{ github.sha }}
    cache-from: type=registry,ref=user/app:buildcache
    cache-to: type=registry,ref=user/app:buildcache,mode=max

Image Scanning

# Scan for vulnerabilities
docker scan myapp:latest

# Using Trivy
trivy image myapp:latest

Debugging

Common Issues

  • Container exits immediately
  • Permission errors
  • Network connectivity
  • Volume mount issues

Debugging Commands

# View container logs
docker logs --tail 50 -f container_name

# Inspect container
docker inspect container_name

# View running processes
docker top container_name

# Check resource usage
docker stats

# Debug networking
docker network inspect bridge

Debug Container

# Add debugging tools to production image
FROM myapp:latest
RUN apk add --no-cache curl wget vim bash
CMD ["/bin/bash"]

Performance Optimization

Image Size Reduction

  • Use Alpine Linux base images
  • Multi-stage builds
  • Remove unnecessary files
  • Combine RUN commands
  • Use .dockerignore

Build Performance

  • Leverage build cache
  • Use BuildKit
  • Parallel builds
  • Cache mount for package managers

Security

Image Scanning

# Scan with Docker Scout
docker scout cves myapp:latest

# Generate SBOM
docker sbom myapp:latest

Runtime Security

  • Read-only root filesystem
  • Drop unnecessary capabilities
  • Use security profiles (AppArmor/SELinux)
  • Limit resources

Monitoring

Container Metrics

  • CPU usage
  • Memory consumption
  • Network I/O
  • Disk usage

Logging

  • Centralized logging with Fluentd
  • Log rotation
  • Structured logging

Resources

Team Support

For Docker-related questions:

  • DevOps Team
  • Platform Engineering Team
  • Security Team (for image scanning)

results matching ""

    No results matching ""