Limit privileges, the filesystem and resources. Here are the main options.
Privileges:
- Drop the Linux capabilities (small pieces of root power) that the app doesn't need. A Node API usually needs none. So use
--cap-drop ALL, and add back only specific ones. - Use
--security-opt no-new-privileges. Then setuid programs cannot raise the process's privileges. - Never use
--privileged. Never mount the Docker socket into app containers.
Filesystem:
- Run with a read-only root filesystem,
--read-only. - Add a
tmpfs(a small in-memory folder) for directories that must be writable, like/tmp.
Resources and network:
- Set memory, CPU and PID limits. Then a runaway or attacked process can't starve the host.
- Don't publish ports that only other containers need.
Security profiles: keep Docker's default seccomp profile enabled. Also keep AppArmor or SELinux enabled.
Image side: use a minimal base image, pin versions, and scan for known vulnerabilities.
- Use
--cap-drop ALLand add back only what the app needs. - Use
no-new-privilegesso processes can't gain more privileges. - Use a
--read-onlyroot filesystem, with atmpfsfor scratch files. - Set memory, CPU and PID limits.
- Avoid
--privilegedand never mount the Docker socket.
Read more