Skip to content

Docker_security

Chapter 12: Docker Security - Container Security Best Practices

Section titled “Chapter 12: Docker Security - Container Security Best Practices”
  1. Introduction to Container Security
  2. Why Container Security Matters
  3. Docker Security Fundamentals
  4. Container Security Best Practices
  5. Linux Kernel Security Features
  6. Docker Content Trust
  7. Image Scanning and Vulnerability Management
  8. Secrets Management
  9. Network Security
  10. Runtime Security
  11. Security Scanning Tools
  12. Security Hardening
  13. Compliance and Auditing
  14. Summary

Container security is a critical aspect of modern DevOps practices. While containers provide isolation, they share the host kernel, making security a shared responsibility.

┌─────────────────────────────────────────────────────────────────────────────┐
│ CONTAINER SECURITY CHALLENGES │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Traditional Security vs Container Security │
│ ──────────────────────────────────────── │
│ │
│ Traditional (VMs) Container │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ App 1 │ │ Container 1 │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ OS │ │ │ │ App │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │
│ └───────┬───────┘ └────────┬────────┘ │
│ │ │ │
│ ┌───────┴───────┐ ┌────────┴────────┐ │
│ │ Hypervisor │ │ Docker Daemon │ │
│ │ (Hard HW) │ │ (Shared Kernel)│ │
│ └───────┬───────┘ └────────┬────────┘ │
│ │ │ │
│ ┌───────┴───────┐ ┌────────┴────────┐ │
│ │ Hardware │ │ Host Kernel │ │
│ └───────────────┘ └─────────────────┘ │
│ │
│ Implications: │
│ • VM: Strong isolation via separate kernels │
│ • Container: Weaker isolation, faster but shared kernel │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Container security follows a defense-in-depth approach with multiple layers:

┌─────────────────────────────────────────────────────────────────────────────┐
│ CONTAINER SECURITY LAYERS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ APPLICATION LAYER │ │
│ │ • Secure coding practices │ │
│ │ • Input validation │ │
│ │ • Dependency management │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ CONTAINER LAYER │ │
│ │ • Minimal base images │ │
│ │ • Non-root user │ │
│ │ • Read-only filesystem │ │
│ │ • Drop capabilities │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ORCHESTRATION LAYER │ │
│ │ • Network policies │ │
│ │ • Resource limits │ │
│ │ • Pod security policies │ │
│ │ • RBAC │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ INFRASTRUCTURE LAYER │ │
│ │ • Host hardening │ │
│ │ • Kernel namespaces │ │
│ │ • SELinux/AppArmor │ │
│ │ • Seccomp │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Understanding potential attack vectors helps prioritize security measures:

┌─────────────────────────────────────────────────────────────────────────────┐
│ CONTAINER ATTACK VECTORS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Common Attack Vectors in Container Environments │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1. COMPROMISED IMAGES │ │
│ │ ├── Malicious base images │ │
│ │ ├── Vulnerable dependencies │ │
│ │ ├── Embedded secrets │ │
│ │ └── Supply chain attacks │ │
│ │ │ │
│ │ 2. CONTAINER ESCALATION │ │
│ │ ├── Kernel exploits │ │
│ │ ├── Privilege escalation │ │
│ │ ├── Capability abuse │ │
│ │ └── Mount escapes │ │
│ │ │ │
│ │ 3. NETWORK ATTACKS │ │
│ │ ├── Man-in-the-middle │ │
│ │ ├── Eavesdropping │ │
│ │ ├── DNS spoofing │ │
│ │ └── Service exploitation │ │
│ │ │ │
│ │ 4. RUNTIME ATTACKS │ │
│ │ ├── Container breakout │ │
│ │ ├── Resource exhaustion │ │
│ │ ├── Denial of service │ │
│ │ └── Cryptomining │ │
│ │ │ │
│ │ 5. SUPPLY CHAIN │ │
│ │ ├── Compromised registries │ │
│ │ ├── Typosquatting │ │
│ │ └── Backdoored images │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
│ Real-world Impact: │
│ • Data breaches - Exposure of sensitive data │
│ • Service disruption - Downtime and revenue loss │
│ • Reputation damage - Loss of customer trust │
│ • Compliance violations - Regulatory penalties │
│ • Cryptojacking - Resource theft for cryptocurrency │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ CONTAINER SECURITY STATISTICS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Recent Security Reports Highlight Critical Concerns: │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 📊 60% of organizations experienced a container security incident │ │
│ │ │ │
│ │ 📊 94% of scanned images contain known vulnerabilities │ │
│ │ │ │
│ │ 📊 67% of images have high or critical severity issues │ │
│ │ │ │
│ │ 📊 75% of developers don't scan containers before deployment │ │
│ │ │ │
│ │ 📊 Top vulnerabilities: │ │
│ │ • Outdated system libraries │ │
│ │ • Application dependencies │ │
│ │ • Base image issues │ │
│ │ • Misconfigurations │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

The Docker daemon runs with root privileges, making its security critical:

/etc/docker/daemon.json
# Secure Docker daemon configuration
{
"icc": false,
"ip-forward": false,
"iptables": true,
"userland-proxy": false,
"live-restore": true,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 64000,
"Soft": 64000
}
},
"default-cgroupns-mode": "host",
"no-new-privileges": true,
"security-options": {
"seccomp-profile": "/etc/docker/seccomp.json",
"apparmor-profile": "docker-default"
}
}
Terminal window
# Create docker group and add users (if not exists)
sudo groupadd docker
sudo usermod -aG docker $USER
# Use rootless Docker (recommended for better security)
# Requires docker-rootless-setuptool.sh

┌─────────────────────────────────────────────────────────────────────────────┐
│ MINIMAL BASE IMAGES COMPARISON │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Full Image (Ubuntu) Minimal Image (Alpine) │
│ ┌───────────────────┐ ┌───────────────────┐ │
│ │ ~900 MB │ │ ~5 MB │ │
│ │ │ │ │ │
│ │ Includes: │ │ Includes: │ │
│ │ • Full OS │ │ • Minimal Linux │ │
│ │ • Package manager│ │ • BusyBox │ │
│ │ • Many libraries│ │ • APK package │ │
│ │ • Development tools│ │ • libc │ │
│ │ │ │ │ │
│ │ Attack Surface: │ │ Attack Surface: │ │
│ │ HIGH │ │ LOW │ │
│ └───────────────────┘ └───────────────────┘ │
│ │
│ Even Better: Distroless Images │
│ ┌───────────────────┐ │
│ │ gcr.io/distroless │ │
│ │ ~2 MB │ │
│ │ │ │
│ │ No shell, no pkg │ │
│ │ manager │ │
│ │ │ │
│ │ Attack Surface: │ │
│ │ MINIMAL │ │
│ └───────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
# Bad: Running as root
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y nginx
CMD ["nginx", "-g", "daemon off;"]
# Good: Running as non-root
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y nginx \
&& useradd -m -s /bin/bash appuser
USER appuser
WORKDIR /home/appuser
# Best: Using minimal image
FROM alpine:3.18
RUN addgroup -g 1000 appgroup && adduser -u 1000 -G appgroup -s /bin/sh -D appuser
COPY --chown=appuser:appgroup . /home/appuser
USER appuser
CMD ["nginx", "-g", "daemon off;"]
Terminal window
# Run container with read-only filesystem
docker run --read-only -d nginx
# Combine with tmpfs for writable areas
docker run --read-only --tmpfs /tmp -d nginx
# In docker-compose
services:
web:
image: nginx
read_only: true
tmpfs:
- /tmp:size=100M,mode=1777

4. Drop All Capabilities and Add Only Required Ones

Section titled “4. Drop All Capabilities and Add Only Required Ones”
Terminal window
# Drop all capabilities, add only NET_BIND_SERVICE
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
# Common capabilities needed:
# - NET_BIND_SERVICE: Bind to privileged ports
# - CHOWN: Change file ownership
# - SETGID/SETUID: Set process IDs
# - SYS_CHROOT: Change root directory
Terminal window
# Limit CPU and memory
docker run --memory=256m --cpus=0.5 nginx
# Limit pids (processes)
docker run --pids-limit=100 nginx
# Limit file descriptors
docker run --ulimit nofile=100:200 nginx

Docker uses Linux namespaces to provide isolation:

┌─────────────────────────────────────────────────────────────────────────────┐
│ LINUX NAMESPACES │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Namespaces provide isolation for: │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────────────────┐ │
│ │ PID Namespace │ │ Process Isolation │ │
│ │ │ │ Container sees only its processes │ │
│ │ Process ID │ │ PID 1 inside container = PID X on host │ │
│ └─────────────────┘ └─────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────────────────┐ │
│ │ NET Namespace │ │ Network Isolation │ │
│ │ │ │ Separate network stack per container │ │
│ │ Network │ │ Virtual eth0, loopback, routing tables │ │
│ └─────────────────┘ └─────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────────────────┐ │
│ │ IPC Namespace │ │ Inter-Process Communication │ │
│ │ │ │ Separate semaphores, shared memory │ │
│ │ IPC │ │ Cannot communicate with host IPC │ │
│ └─────────────────┘ └─────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────────────────┐ │
│ │ MNT Namespace │ │ Filesystem Isolation │ │
│ │ │ │ Separate mount points │ │
│ │ Mount │ │ Rootfs appears as full system │ │
│ └─────────────────┘ └─────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────────────────┐ │
│ │ UTS Namespace │ │ Hostname Isolation │ │
│ │ │ │ Can set different hostname │ │
│ │ UTS │ │ Different domain names possible │ │
│ └─────────────────┘ └─────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────────────────┐ │
│ │ USER Namespace │ │ User ID Mapping │ │
│ │ │ │ Root in container ≠ root on host │ │
│ │ User │ │ Map UID 0 in container to UID 100000 on host │ │
│ └─────────────────┘ └─────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────────### Control Groups (cgroups)
```─┘

bash

docker exec cat /proc/1/cgroup

### Seccomp
Seccomp limits system calls available to containers:
```json
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{
"names": [
"read",
"write",
"open",
"close",
"mmap",
"mprotect",
"brk",
"rt_sigaction",
"rt_sigprocmask",
"ioctl"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
Terminal window
# Use default seccomp profile
docker run --security-opt seccomp=docker-default nginx
# Use custom seccomp profile
docker run --security-opt seccomp=/path/to/profile.json nginx
# Disable seccomp (not recommended for production)
docker run --security-opt seccomp=unconfined nginx
Terminal window
# Run with AppArmor profile
docker run --security-opt apparmor=docker-default nginx
# Check AppArmor status in container
docker exec <container> cat /sys/kernel/security/apparmor/profiles

Terminal window
# Enable Docker Content Trust
export DOCKER_CONTENT_TRUST=1
# Now pulls will verify image signatures
docker pull nginx:latest
# Signing images requires private key
docker trust sign myregistry.io/myimage:latest
Terminal window
# Initialize trust (first time)
docker trust init
# Add signers
docker trust key load key.pem
docker trust signer add --key key.pem publisherName myregistry.io
# View signers
docker trust inspect myregistry.io/myimage:latest

Image Scanning and Vulnerability Management

Section titled “Image Scanning and Vulnerability Management”
Terminal window
# Using Docker Scout (recommended)
docker scout cves myimage:latest
# Using Trivy
trivy image myimage:latest
# Using Clair
clair-scanner --ip 127.0.0.1 myimage:latest
# GitHub Actions example
name: Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Trivy scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload results to GitHub Security
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
┌─────────────────────────────────────────────────────────────────────────────┐
│ VULNERABILITY MANAGEMENT PROCESS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 1. SCAN │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Local │ │ CI/CD │ │ Registry │ │ │
│ │ │ Scanner │ │ Scanner │ │ Scanner │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 2. ASSESS │ │
│ │ │ │
│ │ Severity Levels: │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ CRITICAL│ │ HIGH │ │ MEDIUM │ │ LOW │ │ │
│ │ │ Fix Now │ │ Fix Soon│ │ Plan Fix│ │ Accept │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │ │
│ │ Consider: Exploitability, CVSS score, Asset criticality │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 3. REMEDIATE │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Update │ │ Remove │ │ Apply │ │ │
│ │ │ Base Image │ │ Dependency │ │ Patch │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 4. VERIFY │ │
│ │ │ │
│ │ Re-scan to confirm remediation │ │
│ │ Update baseline for acceptable risks │ │
│ │ Document exceptions │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Terminal window
# Create a secret
echo "my-secret-password" | docker secret create db_password -
# Create secret from file
docker secret create db_password ./password.txt
# List secrets
docker secret ls
# Use secret in service
docker service create \
--name myapp \
--secret db_password \
myapp:latest
# Access secret in container
# File-based: /run/secrets/<secret_name>
cat /run/secrets/db_password
version: '3.8'
services:
web:
image: nginx
secrets:
- db_password
- api_key
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
external: true
┌─────────────────────────────────────────────────────────────────────────────┐
│ SECRETS MANAGEMENT BEST PRACTICES │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ✓ DO: │
│ ───────────────────────────────────────────────────────────────────── │
│ • Use Docker secrets in Swarm / Kubernetes secrets in K8s │
│ • Rotate secrets regularly │
│ • Use external secrets management (Vault, AWS Secrets Manager) │
│ • Audit secret access │
│ • Enable encryption at rest │
│ • Use separate secrets per environment │
│ │
│ ✗ DON'T: │
│ ───────────────────────────────────────────────────────────────────── │
│ • Never commit secrets to version control │
│ • Don't store secrets in environment variables │
│ • Don't use same secrets across environments │
│ • Don't share secret files │
│ • Never log secrets │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Terminal window
# Create custom network with isolation
docker network create --driver bridge --internal myapp-network
# Run containers on specific networks
docker run --network myapp-network nginx
# Use network aliases for service discovery
docker run --network-alias api myapp:latest
Terminal window
# Create encrypted overlay network
docker network create \
--driver overlay \
--encrypted \
--attachable \
secure-network
Terminal window
# Don't expose unnecessary ports
# Bad: Expose all
docker run -p 0.0.0.0:8080:8080 myapp
# Good: Bind to localhost only
docker run -p 127.0.0.1:8080:8080 myapp
# Good: Minimal exposure
docker run -p 80:8080 myapp

Terminal window
# Enable additional security options
docker run \
--security-opt no-new-privileges:true \
--cap-drop ALL \
--read-only \
--tmpfs /tmp \
nginx
# Add specific capabilities
docker run \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--cap-add CHOWN \
nginx
Terminal window
# Install Falco
docker run -d \
--name falco \
--privileged \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /proc:/host/proc:ro \
falcosecurity/falco
# Example Falco rule for container security
- rule: Shell in container
desc: A shell was spawned in a container
condition: >
container.id != host and
proc.name = bash
output: "Shell spawned in container (user=%user.name %container.info)"
priority: WARNING

┌─────────────────────────────────────────────────────────────────────────────┐
│ CONTAINER SECURITY TOOLS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Image Scanning │
│ ───────────────── │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ Trivy │ │ Clair │ │ Anchore │ │
│ │ Free/Open │ │ Open Source │ │ Enterprise │ │
│ │ Fast, Easy │ │ Static │ │ Deep │ │
│ │ │ │ Analysis │ │ Inspection │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
│ │
│ Runtime Security │
│ ───────────────── │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ Falco │ │ Sysdig │ │ Aqua │ │
│ │ Open Source │ │ Commercial │ │ Enterprise │ │
│ │ Kernel-based│ │ Full Stack │ │ Complete │ │
│ │ Monitoring │ │ Security │ │ Platform │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
│ │
│ Registry Security │
│ ───────────────── │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ Docker Hub │ │ Harbor │ │ ACR/GCR/ECR │ │
│ │ Security │ │ Open Source │ │ Native Scan │ │
│ │ Scanning │ │ Registry │ │ │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Terminal window
# Run Docker Bench
docker run --rm -it \
--net host \
--pid host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc/docker:/etc/docker \
docker/bench-security
┌─────────────────────────────────────────────────────────────────────────────┐
│ DOCKER SECURITY CHECKLIST │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Infrastructure │
│ ─────────────── │
│ □ Keep Docker engine updated │
│ □ Use minimal base images │
│ □ Regular security scans │
│ □ Enable Docker Content Trust │
│ □ Use private registries │
│ │
│ Container Configuration │
│ ───────────────────── │
│ □ Run as non-root user │
│ □ Use read-only filesystem │
│ □ Drop all capabilities │
│ □ Limit resources (memory, CPU) │
│ □ Disable inter-container communication │
│ □ Use specific image tags │
│ │
│ Network Security │
│ ──────────────── │
│ □ Use custom networks │
│ □ Encrypt overlay networks │
│ □ Minimize port exposure │
│ □ Use TLS for registry │
│ □ Implement network policies │
│ │
│ Secrets Management │
│ ─────────────────── │
│ □ Use Docker secrets │
│ □ Rotate secrets regularly │
│ □ Use external secrets management │
│ □ Never commit secrets │
│ │
│ Monitoring & Logging │
│ ──────────────────── │
│ □ Enable audit logging │
│ □ Monitor for anomalies │
│ □ Set up alerts │
│ □ Review logs regularly │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

The CIS Docker Benchmark provides security configuration guidelines:

Terminal window
# Docker Bench includes CIS checks
docker run -d \
--name docker-bench \
--net host \
--pid host \
-v /etc/docker:/etc/docker \
docker/bench-security
┌─────────────────────────────────────────────────────────────────────────────┐
│ COMPLIANCE CONSIDERATIONS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Common Compliance Frameworks: │
│ │
│ • SOC 2 - Security, availability, confidentiality │
│ • PCI-DSS - Payment card industry │
│ • HIPAA - Healthcare data │
│ • GDPR - EU data protection │
│ • ISO 27001 - Information security │
│ │
│ Audit Requirements: │
│ ───────────────────────────────────────────────────────────────────── │
│ • Document all container configurations │
│ • Maintain image provenance │
│ • Log all security events │
│ • Regular vulnerability scans │
│ • Incident response procedures │
│ • Access control documentation │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

  1. Defense in Depth - Layer multiple security controls
  2. Minimal Attack Surface - Use minimal images, drop capabilities
  3. Run as Non-Root - Never run containers as root unless necessary
  4. Scan Regularly - Integrate security scanning into CI/CD
  5. Manage Secrets Properly - Use Docker secrets or external solutions
  6. Monitor Continuously - Implement runtime security monitoring
  7. Keep Updated - Patch vulnerabilities regularly
  8. Follow Best Practices - Use CIS benchmarks and security guides
Terminal window
# Run securely
docker run \
--rm \
--cap-drop ALL \
--read-only \
--pids-limit 100 \
--memory=256m \
--cpus=0.5 \
--user 1000:1000 \
nginx
# Security scanning
docker scout cves myimage:latest
trivy image myimage:latest
# Docker bench
docker run --rm -it --net host --pid host \
-v /var/run/docker.sock:/var/run/docker.sock \
docker/bench-security

In the next chapter, we’ll explore Docker Monitoring (Chapter 13), covering:

  • Container logging best practices
  • Monitoring tools and metrics
  • Log aggregation
  • Alerting strategies