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
- Use a non-root user: Avoid running as root
- Scan for vulnerabilities: Regular image scans
- Use secrets: Don't hardcode passwords
- Limit resources: Set CPU and memory limits
- Update regularly: Update the base image and dependencies
- Use internal networks: For internal services
- 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.