Docker Security and Optimization: Introduction and Setup

Docker security and performance optimization are critical for production deployments. This guide covers comprehensive security hardening, performance tuning, and operational best practices for containerized environments.

Docker Security Fundamentals

Security Model Overview

┌─────────────────────────────────────────────────────────┐
│                 Host Operating System                   │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │
│  │   Kernel    │  │  Namespaces │  │   cgroups   │     │
│  │ Capabilities│  │             │  │             │     │
│  └─────────────┘  └─────────────┘  └─────────────┘     │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │
│  │   SELinux/  │  │  AppArmor   │  │   seccomp   │     │
│  │  AppArmor   │  │             │  │             │     │
│  └─────────────┘  └─────────────┘  └─────────────┘     │
├─────────────────────────────────────────────────────────┤
│                 Docker Engine                           │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │
│  │ Container 1 │  │ Container 2 │  │ Container 3 │     │
│  └─────────────┘  └─────────────┘  └─────────────┘     │
└─────────────────────────────────────────────────────────┘

Basic Security Commands

# Run container with security options
docker run --security-opt no-new-privileges:true \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=100m \
  nginx

# Run as non-root user
docker run --user 1000:1000 \
  -v /etc/passwd:/etc/passwd:ro \
  -v /etc/group:/etc/group:ro \
  alpine id

# Limit resources
docker run --memory=512m \
  --cpus="1.5" \
  --pids-limit=100 \
  --ulimit nofile=1024:1024 \
  myapp

# Network security
docker run --network none alpine
docker run --network custom-network \
  --ip 172.20.0.10 \
  myapp

Container Hardening Basics

Secure Dockerfile Practices

# Use specific versions, not latest
FROM node:16.17.0-alpine3.16

# Create non-root user early
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001 -G nodejs

# Set working directory
WORKDIR /app

# Copy package files first for better caching
COPY package*.json ./

# Install dependencies as root, then switch
RUN npm ci --only=production && \
    npm cache clean --force && \
    chown -R nextjs:nodejs /app

# Copy application files
COPY --chown=nextjs:nodejs . .

# Switch to non-root user
USER nextjs

# Remove unnecessary packages
RUN apk del --purge \
    && rm -rf /var/cache/apk/* \
    && rm -rf /tmp/*

# Set secure permissions
RUN chmod -R 755 /app && \
    chmod 644 /app/package.json

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Expose port
EXPOSE 3000

# Use exec form for CMD
CMD ["node", "server.js"]

Runtime Security Configuration

# Comprehensive security flags
docker run -d \
  --name secure-app \
  --user 1000:1000 \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=100m \
  --tmpfs /var/run:rw,noexec,nosuid,size=50m \
  --cap-drop ALL \
  --cap-add CHOWN \
  --cap-add SETGID \
  --cap-add SETUID \
  --security-opt no-new-privileges:true \
  --security-opt apparmor:docker-default \
  --security-opt seccomp:default \
  --memory=512m \
  --memory-swap=512m \
  --cpu-shares=512 \
  --pids-limit=100 \
  --ulimit nofile=1024:1024 \
  --ulimit nproc=64:64 \
  --restart=unless-stopped \
  myapp:latest

Performance Optimization Basics

Resource Management

# CPU optimization
docker run -d \
  --cpus="2.5" \
  --cpu-shares=1024 \
  --cpuset-cpus="0,1" \
  --cpu-quota=50000 \
  --cpu-period=100000 \
  myapp

# Memory optimization
docker run -d \
  --memory=2g \
  --memory-swap=2g \
  --memory-reservation=1g \
  --oom-kill-disable=false \
  --kernel-memory=500m \
  myapp

# I/O optimization
docker run -d \
  --device-read-bps /dev/sda:50mb \
  --device-write-bps /dev/sda:50mb \
  --device-read-iops /dev/sda:1000 \
  --device-write-iops /dev/sda:1000 \
  myapp

# Network optimization
docker run -d \
  --sysctl net.core.somaxconn=65535 \
  --sysctl net.ipv4.tcp_max_syn_backlog=65535 \
  --sysctl net.core.rmem_max=134217728 \
  --sysctl net.core.wmem_max=134217728 \
  myapp

Docker Daemon Optimization

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ],
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 64000,
      "Soft": 64000
    }
  },
  "max-concurrent-downloads": 10,
  "max-concurrent-uploads": 5,
  "default-shm-size": "128M",
  "userland-proxy": false,
  "experimental": false,
  "metrics-addr": "127.0.0.1:9323",
  "live-restore": true
}

Security Scanning and Assessment

Image Vulnerability Scanning

# Install and use Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# Scan image for vulnerabilities
trivy image nginx:latest

# Scan with specific severity
trivy image --severity HIGH,CRITICAL nginx:latest

# Scan and output to file
trivy image --format json --output results.json nginx:latest

# Scan filesystem
trivy fs .

# Scan with ignore file
trivy image --ignorefile .trivyignore nginx:latest

.trivyignore example:

# Ignore specific CVEs
CVE-2021-12345
CVE-2021-67890

# Ignore by package
pkg:npm/[email protected]

# Ignore by severity
MEDIUM
LOW

Container Runtime Security

# Use Docker Bench Security
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
sudo ./docker-bench-security.sh

# Use Falco for runtime security
docker run -i -t \
  --name falco \
  --privileged \
  -v /var/run/docker.sock:/host/var/run/docker.sock \
  -v /dev:/host/dev \
  -v /proc:/host/proc:ro \
  -v /boot:/host/boot:ro \
  -v /lib/modules:/host/lib/modules:ro \
  -v /usr:/host/usr:ro \
  falcosecurity/falco:latest

# Use Sysdig for monitoring
docker run -d --name sysdig-agent \
  --restart always \
  --privileged \
  --net host \
  --pid host \
  -e ACCESS_KEY=your-access-key \
  -e SECURE=true \
  -v /var/run/docker.sock:/host/var/run/docker.sock \
  -v /dev:/host/dev \
  -v /proc:/host/proc:ro \
  -v /boot:/host/boot:ro \
  -v /lib/modules:/host/lib/modules:ro \
  -v /usr:/host/usr:ro \
  sysdig/agent

Secrets Management

Docker Secrets (Swarm Mode)

# Create secret from file
echo "mypassword" | docker secret create db_password -

# Create secret from stdin
docker secret create ssl_cert cert.pem

# List secrets
docker secret ls

# Use secret in service
docker service create \
  --name myapp \
  --secret db_password \
  --secret ssl_cert \
  myapp:latest

# Access secret in container (available at /run/secrets/secret_name)
docker exec container cat /run/secrets/db_password

External Secrets Management

# docker-compose.yml with external secrets
version: '3.8'

services:
  app:
    image: myapp
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password
      - API_KEY_FILE=/run/secrets/api_key
    secrets:
      - db_password
      - api_key
    volumes:
      - app_data:/data

  vault:
    image: vault:latest
    cap_add:
      - IPC_LOCK
    environment:
      - VAULT_DEV_ROOT_TOKEN_ID=myroot
      - VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200
    ports:
      - "8200:8200"

secrets:
  db_password:
    external: true
  api_key:
    external: true

volumes:
  app_data:

Monitoring and Logging Setup

Security Monitoring

# docker-compose.security-monitoring.yml
version: '3.8'

services:
  # Security event collector
  falco:
    image: falcosecurity/falco:latest
    privileged: true
    volumes:
      - /var/run/docker.sock:/host/var/run/docker.sock
      - /dev:/host/dev
      - /proc:/host/proc:ro
      - /boot:/host/boot:ro
      - /lib/modules:/host/lib/modules:ro
      - /usr:/host/usr:ro
      - ./falco/falco.yaml:/etc/falco/falco.yaml:ro
    environment:
      - FALCO_GRPC_ENABLED=true
      - FALCO_GRPC_BIND_ADDRESS=0.0.0.0:5060

  # Log aggregation
  fluentd:
    image: fluent/fluentd:latest
    volumes:
      - ./fluentd/fluent.conf:/fluentd/etc/fluent.conf:ro
      - /var/log:/var/log:ro
    ports:
      - "24224:24224"

  # Metrics collection
  node-exporter:
    image: prom/node-exporter:latest
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'

  # Container metrics
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    ports:
      - "8080:8080"

Performance Monitoring

# Monitor container performance
docker stats

# Detailed container inspection
docker exec container top
docker exec container ps aux
docker exec container netstat -tlnp
docker exec container iostat -x 1

# System-wide monitoring
htop
iotop
nethogs
iftop

# Docker system information
docker system df
docker system events
docker system info

Compliance and Governance

CIS Docker Benchmark

Key security controls:

  1. Host Configuration

    • Keep Docker up to date
    • Use trusted users only
    • Audit Docker daemon and files
    • Set up proper logging
  2. Docker Daemon Configuration

    • Restrict network traffic between containers
    • Set logging level to ‘info’
    • Allow Docker to make changes to iptables
    • Do not use insecure registries
  3. Docker Daemon Configuration Files

    • Verify ownership and permissions
    • Secure Docker socket
    • Protect Docker daemon configuration
  4. Container Images and Build Files

    • Create user for containers
    • Use trusted base images
    • Do not install unnecessary packages
    • Scan images for vulnerabilities
  5. Container Runtime

    • Do not share host’s network namespace
    • Limit memory usage
    • Set container CPU priority appropriately
    • Mount container’s root filesystem as read-only

Automated Compliance Checking

#!/bin/bash
# docker-security-audit.sh

echo "Docker Security Audit Report"
echo "============================"
echo "Date: $(date)"
echo

# Check Docker version
echo "1. Docker Version Check"
docker --version
echo

# Check running containers security
echo "2. Container Security Analysis"
for container in $(docker ps -q); do
    echo "Container: $container"
    
    # Check if running as root
    user=$(docker inspect --format='{{.Config.User}}' $container)
    if [ -z "$user" ]; then
        echo "  WARNING: Container running as root"
    else
        echo "  OK: Running as user $user"
    fi
    
    # Check privileged mode
    privileged=$(docker inspect --format='{{.HostConfig.Privileged}}' $container)
    if [ "$privileged" = "true" ]; then
        echo "  WARNING: Container running in privileged mode"
    else
        echo "  OK: Not running in privileged mode"
    fi
    
    # Check read-only root filesystem
    readonly=$(docker inspect --format='{{.HostConfig.ReadonlyRootfs}}' $container)
    if [ "$readonly" = "false" ]; then
        echo "  WARNING: Root filesystem is writable"
    else
        echo "  OK: Root filesystem is read-only"
    fi
    
    echo
done

# Check image vulnerabilities
echo "3. Image Vulnerability Scan"
for image in $(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>"); do
    echo "Scanning $image..."
    trivy image --severity HIGH,CRITICAL --quiet $image
done

echo "Audit completed."

Summary

In this introduction, you’ve learned:

Security Fundamentals

  • Security Model: Understanding Docker’s security architecture and isolation mechanisms
  • Container Hardening: Secure Dockerfile practices and runtime security configuration
  • Vulnerability Scanning: Using Trivy and other tools for security assessment
  • Secrets Management: Proper handling of sensitive data in containers

Performance Basics

  • Resource Management: CPU, memory, and I/O optimization techniques
  • Docker Daemon Tuning: Configuration for optimal performance
  • Monitoring Setup: Tools and techniques for performance monitoring

Operational Security

  • Compliance: CIS Docker Benchmark and security controls
  • Monitoring: Security event collection and analysis
  • Governance: Automated compliance checking and reporting

Key Concepts Mastered

  • Defense in Depth: Multiple layers of security controls
  • Least Privilege: Running containers with minimal permissions
  • Resource Limits: Preventing resource exhaustion attacks
  • Continuous Monitoring: Real-time security and performance monitoring

Next Steps: Part 2 explores core security concepts including advanced hardening techniques, performance optimization strategies, and comprehensive monitoring solutions that form the foundation of production-ready Docker deployments.