Docker Security Best Practices
Defense-in-depth for containerized applications.
Image Security
Use Minimal Base Images
# Prefer minimal images
FROM alpine:3.19
FROM node:20-alpine
FROM python:3.12-slim
FROM gcr.io/distroless/static
FROM scratchPin Image Versions
# Bad: Unpredictable
FROM node:latest
# Good: Specific version
FROM node:20.10.0-alpine3.19
# Best: Immutable digest
FROM node@sha256:abc123...Scan Images
# Docker Scout (built-in)
docker scout cves myimage:latest
docker scout recommendations myimage:latest
# Trivy
trivy image myimage:latest
# Grype
grype myimage:latestContainer Security
Run as Non-Root
# Create and use non-root user
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
USER appuserDrop Capabilities
# Drop all, add only needed
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp
# Common safe capabilities to drop
docker run \
--cap-drop NET_RAW \
--cap-drop SYS_ADMIN \
--cap-drop SETUID \
--cap-drop SETGID \
myappSecurity Options
# Prevent privilege escalation
docker run --security-opt no-new-privileges myapp
# Use seccomp profile
docker run --security-opt seccomp=./profile.json myapp
# AppArmor profile
docker run --security-opt apparmor=docker-default myappRead-Only Filesystem
docker run --read-only \
--tmpfs /tmp \
--tmpfs /var/run \
myappResource Limits
docker run \
--memory 512m \
--memory-swap 512m \
--cpus 0.5 \
--pids-limit 100 \
myappNetwork Security
# Internal networks (no external access)
docker network create --internal backend
# Disable inter-container communication
docker network create --opt com.docker.network.bridge.enable_icc=false isolatedSecrets Management
# docker-compose.yml
services:
app:
secrets:
- db_password
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txtSecurity Checklist
| Category | Check |
|---|---|
| Image | Use minimal base |
| Image | Pin versions |
| Image | Scan for CVEs |
| Container | Run as non-root |
| Container | Drop capabilities |
| Container | Read-only filesystem |
| Container | Resource limits |
| Network | Isolate sensitive services |
| Secrets | Never in images/env vars |
| Host | Keep Docker updated |
Docker Daemon Security
# /etc/docker/daemon.json
{
"userns-remap": "default",
"no-new-privileges": true,
"icc": false,
"live-restore": true,
"userland-proxy": false
} - docker
- security
- hardening
- best practices
- defense