Skillversitas

Docker Security

Docker security covers container isolation, secrets management, and security configuration.

Container Isolation

# Run with a non-root user
docker run -d --user 1000:1000 myapp

# Limit capabilities
docker run -d --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

# Disable privilege escalation
docker run -d --security-opt=no-new-privileges myapp

# Read-only filesystem
docker run -d --read-only --tmpfs /tmp myapp

Secrets Management

# Use Docker secrets (Swarm)
echo "secret123" | docker secret create db_password -

# Use environment variables
docker run -d -e DB_PASSWORD=secret123 myapp

# Use Docker config
docker config create db_config ./config.json

Image Security

# Scan for vulnerabilities
docker scout cves myapp:latest

# Use an official image
docker pull node:18-alpine

# Update images regularly
docker pull myapp:latest

# Sign an image
docker trust sign myapp:latest

Network Security

# Use an internal network
docker network create --internal secure-net

# Don't expose unneeded ports
# Wrong:
docker run -d -p 3306:3306 mysql
# Right:
docker run -d -p 127.0.0.1:3306:3306 mysql

Resource Limits

# Limit CPU
docker run -d --cpus="1.5" myapp

# Limit memory
docker run -d --memory="512m" --memory-swap="1g" myapp

# Limit PIDs
docker run -d --pids-limit=100 myapp

Use Case: Application Security

version: '3.8'

services:
  database:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G

  api:
    build: ./backend
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    networks:
      - backend
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL

secrets:
  db_password:
    file: ./secrets/db_password.txt

networks:
  backend:
    internal: true

Docker Bench Security

# Run Docker Bench
docker run --rm --net host --pid host --userns host --cap-add audit_control \
  -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
  -v /var/lib:/var/lib:ro \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -v /usr/lib/systemd:/usr/lib/systemd:ro \
  docker/docker-bench-security

Everyday Use Case

Case: A developer needs to secure the application.

# Scan the image before pushing
docker scout cves myapp:latest

# Run with security constraints
docker run -d \
  --user 1000:1000 \
  --read-only \
  --tmpfs /tmp \
  --security-opt=no-new-privileges \
  --cap-drop=ALL \
  myapp:latest

Best Practices

  1. Use a non-root user: Avoid running as root
  2. Scan for vulnerabilities: Regular image scans
  3. Use secrets: Don't hardcode passwords
  4. Limit resources: Set CPU and memory limits
  5. Update regularly: Update the base image and dependencies
  6. Use internal networks: For internal services
  7. Monitor: Watch container activity

Use Case: Security Audit

# View all running containers
docker ps

# Check security options
docker inspect --format='{{.HostConfig.SecurityOpt}}' container_name

# Check capabilities
docker inspect --format='{{.HostConfig.CapAdd}}' container_name

# Check resource limits
docker inspect --format='{{.HostConfig.Memory}}' container_name

Conclusion

Docker security should be a priority. Use a non-root user, scan for vulnerabilities, and set resource limits to protect your application.