Docker Security Practices

This chapter covers Docker container security best practices for building and running secure containerized applications.

Image Security

Use Official Images

# ✅ Use official images
FROM node:20-alpine

# ❌ Avoid unknown sources
FROM random-user/node-custom

Pin Image Versions

# ✅ Use specific version tags
FROM node:20.11.1-alpine3.19

# ⚠️ Avoid latest (may introduce unknown changes)
FROM node:latest

Scan for Vulnerabilities

docker scout cves myimage:latest

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image myimage:latest

Minimize Images

FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o main .

FROM scratch
COPY --from=builder /app/main /main
CMD ["/main"]

Container Runtime Security

Use Non-Root Users

FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm ci
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
CMD ["node", "server.js"]

Read-Only Filesystem

docker run --read-only --tmpfs /tmp --tmpfs /var/run myapp:latest

Limit Capabilities

docker run --cap-drop ALL myapp:latest
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp:latest
docker run --security-opt no-new-privileges myapp:latest

Resource Limits

docker run -m 256m --cpus 0.5 myapp:latest
docker run --pids-limit 100 myapp:latest

Network Security

Network Isolation

docker network create --internal backend-net
docker network create frontend-net

docker run -d --name db --network backend-net postgres:16
docker run -d --name app --network frontend-net myapp
docker network connect backend-net app

Secrets Management

Environment Variable Security

# ❌ Don't hardcode secrets in Dockerfile
ENV DB_PASSWORD=secret123

# ✅ Pass at runtime
docker run -e DB_PASSWORD=secret123 myapp

# ✅ Use .env file
docker run --env-file .env myapp

.dockerignore

.env
.env.*
*.key
*.pem
secrets/
.git

Security Checklist

CheckDescription
✅ Use official base imagesEnsure trusted image sources
✅ Pin version tagsAvoid unexpected changes
✅ Use non-root userReduce container escape risk
✅ Multi-stage buildsReduce attack surface
✅ No secrets in imagesKeep passwords/keys out of images
✅ Minimize packagesOnly install necessary dependencies
✅ Use COPY not ADDADD has implicit behaviors
✅ Set HEALTHCHECKMonitor container health

Chapter Summary

Docker security requires a multi-layered approach covering image building, container runtime, networking, and secrets management. Follow the principle of least privilege and regularly scan for vulnerabilities.

Further Reading