DEV Community

Cover image for 🛡️ Docker Security Best Practices — From Dockerfile to Production
Latchu@DevOps
Latchu@DevOps

Posted on

🛡️ Docker Security Best Practices — From Dockerfile to Production

Docker makes it easy to package and run applications, but with great power comes great responsibility — especially when it comes to security.

In this post, we’ll explore global standard security best practices for:

  • Writing secure Dockerfiles
  • Building hardened Docker images
  • Running containers safely in production

Let’s lock it down 🔒


📝 1. Secure Your Dockerfile Like a Pro

✅ Best Practice 🧠 Why It Matters
Use minimal base images (alpine, distroless) Smaller, less vulnerable surface area
Pin image versions (node:18, not latest) Avoid breaking changes & unknown patches
Use a non-root user (USER appuser) Least privilege by default
Avoid copying secrets (.env, API keys) Prevent secret leaks in image
Use .dockerignore Don’t accidentally copy sensitive files
Multi-stage builds Remove build tools from final image

🔧 Example Dockerfile

FROM node:18-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist .
USER node
CMD ["node", "index.js"]
Enter fullscreen mode Exit fullscreen mode

📦 2. Best Practices for Building Docker Images

✅ Best Practice 🧠 Why It Matters
Use trusted base images from official sources Avoid infected or outdated layers
Regularly scan images for vulnerabilities Identify known CVEs early
Sign your images (Docker Content Trust, Cosign) Verify source integrity
Remove unused tools, temp files, package caches Reduce attack surface & image size
Use versioned tags (v1.0-20240605) Make rollback and audits easier

Tools: Trivy, Grype, Snyk, Docker scan


🚀 3. Run Containers Securely in Production

✅ Best Practice 🧠 Why It Matters
Use --read-only file systems Prevent file tampering
Drop unneeded Linux capabilities (--cap-drop=ALL) Reduce kernel exposure
Set memory/CPU limits Prevent denial-of-service attacks
Run as a non-root UID/GID Limit privilege even further
Use --no-new-privileges Block runtime privilege escalation
Expose only necessary ports Minimize network attack surface
Pull secrets securely (e.g. SSM, Vault) Avoid hardcoded secrets in images

🔐 Secure Docker Run Example

docker run \
  --read-only \
  --cap-drop=ALL \
  --memory=512m \
  --user 1001:1001 \
  --security-opt no-new-privileges:true \
  myapp:secure
Enter fullscreen mode Exit fullscreen mode

🛠 Bonus Security Tools You Should Know

Tool Purpose
Trivy / Grype Scan images for CVEs
Docker Bench Run security checks (CIS benchmark)
Cosign / Notary Sign and verify image integrity
Falco Detect runtime anomalies

✅ TL;DR — Quick Checklist

🔹 Dockerfile

  • Use minimal base
  • Add .dockerignore
  • Drop root access

🔹 Docker Image

  • Sign and scan images
  • Remove temp files
  • Pin image versions

🔹 Container Runtime

  • Limit privileges
  • Add resource limits
  • Don’t expose what’s not needed

🧠 Final Thoughts

Security starts at build time — not after a breach.

Adopting these Docker security practices ensures your containers are lean, locked down, and production-ready.

Top comments (0)