Docker Security Hardening: Production Checklist

by Ivan Ivanov dockersecurityhardeningdevops

Essential security hardening steps for Docker containers and host systems. From user namespaces to read-only filesystems.

Containers are not secure by default. Docker's default settings prioritize convenience over security. Here's my production hardening checklist based on real-world incident response.

Docker Daemon Security

1. Run as Rootless

dockerd-rootless-setuptool.sh install

Rootless Docker removes kernel capabilities and prevents privilege escalation from container to host.

2. Enable User Namespace Remapping

{
  "userns-remap": "default"
}

Each container runs with an unprivileged UID/GID range on the host.

3. Restrict Capabilities

Drop all capabilities by default, add only what's needed:

security_opt:
  - no-new-privileges:true
  - cap-drop=ALL
  - cap-add=NET_BIND_SERVICE  # only if your app binds to <1024

Container Image Hardening

Use Minimal Base Images

FROM alpine:3.19  # 5MB vs ubuntu:2204's 80MB

Or even better:

FROM scratch  # for statically compiled binaries
COPY app /
CMD ["/app"]

Multi-Stage Builds for Smaller Images

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

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

Scan Images for Vulnerabilities

docker scan myapp:latest
# or
trivy image myapp:latest

Integrate scanning into CI:

- name: Scan for vulnerabilities
  run: |
    trivy image --exit-code 1 --severity HIGH $IMAGE

Runtime Security

Read-Only Filesystem

read_only: true
tmpfs:
  - /tmp
  - /run

No Root User in Container

RUN addgroup -g 1000 appuser && \
    adduser -u 1000 -G appuser -s /bin/sh -D appuser
USER appuser

Seccomp and AppArmor Profiles

security_opt:
  - seccomp=./seccomp-profile.json
  - apparmor=docker-profile

Network Segmentation

Bridge Network Isolation

docker network create --driver bridge isolated-net
docker run --network isolated-net myapp

Prevent Container-to-Host Communication

iptables -I DOCKER-USER -i br-xxxx -o docker0 -j DROP

Resource Limits

Prevent DoS attacks:

deploy:
  resources:
    limits:
      memory: 512M
      cpus: '1.0'

Docker Content Trust

export DOCKER_CONTENT_TRUST=1
docker pull myapp:1.0  # only accepts signed images

Host System Hardening

  • Keep Docker Engine updated
  • Use SELinux/AppArmor on host
  • Disable inter-container communication by default: --icc=false
  • Audit Docker daemon logs
  • Regular security scanning with Lynis or OpenSCAP

Conclusion

Security is defense in depth. Apply these layers systematically. A single missed step could be your next breach.