Docker security basics
Topic: Containers core
Summary
Run containers as non-root when possible; use read-only root filesystem and drop capabilities; scan images for vulnerabilities; keep the host and Docker updated. Use this when hardening containerized workloads or when reviewing container security.
Intent: How-to
Quick answer
- Non-root: add USER in Dockerfile (e.g. USER appuser); ensure files are owned by that user. Run with --user in docker run if needed. Read-only: docker run --read-only; use tmpfs for writable dirs (e.g. /tmp).
- Limit capabilities: docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE if only that is needed. Avoid --privileged. Use --security-opt no-new-privileges. Limit resources: --memory, --cpus.
- Image: use minimal base (alpine); pin versions; scan with docker scout or trivy. Do not store secrets in images; use env or secrets at runtime. Keep host and Docker updated.
Prerequisites
Steps
-
Run as non-root
In Dockerfile: create user with adduser; chown app dirs; USER appuser. Build and run; verify process is not root inside container (whoami). Use --user uid:gid in docker run to override.
-
Read-only and capabilities
docker run --read-only --tmpfs /tmp myimage. Drop all caps and add only needed: --cap-drop=ALL --cap-add=NET_BIND_SERVICE. Add --security-opt no-new-privileges.
-
Resource limits
docker run --memory=512m --cpus=0.5 myimage. Prevents one container from exhausting host. In Compose: deploy.resources.limits.memory and cpus.
-
Image and host
Use specific base tags; run docker scout or trivy image myimage. Inject secrets at runtime (env, mount); do not bake into image. Patch host and Docker; restrict who can run Docker (docker group).
Summary
Run as non-root; use read-only root and drop capabilities; limit resources; scan images and keep host updated. Use this to harden container deployments.
Prerequisites
Steps
Step 1: Run as non-root
Add a non-root user in the Dockerfile and set USER; verify at runtime.
Step 2: Read-only and capabilities
Use —read-only and tmpfs; drop unneeded capabilities; set no-new-privileges.
Step 3: Resource limits
Set memory and CPU limits in run or Compose.
Step 4: Image and host
Pin base images; scan for vulnerabilities; inject secrets at runtime; patch host and Docker.
Verification
- Container runs as non-root; read-only and capabilities are set; limits are applied; no secrets in image.
Troubleshooting
Permission denied — Ensure files in image are owned by the USER; or use tmpfs for writable dirs. App needs capability — Add only that cap with —cap-add; avoid —privileged.