Docker Container Hardening: Essential Security Practices
Running Docker containers with default settings is like leaving your front door unlocked. Here’s a practical guide to hardening your containers and reducing your attack surface.
The Core Principles
Most Docker containers run as root by default and get far more capabilities than they actually need. This creates unnecessary risk if a container is compromised. The solution? Apply the principle of least privilege across every aspect of your container configuration.
Key Hardening Techniques
Run as non-root user
user: "99:100" # nobody:users on Unraid
Drop all capabilities by default
cap_drop:
- ALL
Only add back specific capabilities if absolutely required.
Enable security restrictions
security_opt:
- no-new-privileges:true
read_only: true # if possible
tty: false
stdin_open: false
Harden /tmp to prevent payload execution
tmpfs:
- /tmp:rw,noexec,nosuid,nodev,size=512m
Set resource limits
pids_limit: 512
mem_limit: 3g
cpus: 3
Mount volumes read-only when possible
volumes:
- /mnt/data/movies:/movies:ro
Control logging to prevent log bombs
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
Using Templates
Save time with compose anchors:
x-lockdown: &lockdown
read_only: true
security_opt:
- "no-new-privileges=true"
cap_drop:
- ALL
tmpfs:
- /tmp:rw,noexec,nosuid,nodev,size=512m
services:
myapp:
<<: *lockdown
Important Notes
Some containers won’t work with all restrictions enabled. Use docker logs <container> to troubleshoot and selectively relax constraints as needed. For internet-facing containers, consider running them in a DMZ network or separate VM for additional isolation.
These configurations significantly reduce blast radius without eliminating all risk. Defense in depth is key.
Credit: Based on excellent advice from the /r/selfhosted community https://www.reddit.com/r/selfhosted/comments/1pr74r4/comment/nv07sp4/
Write a comment