0 / 11 lessons — 0%
Lesson 11 / 11 ✅

Best practices & security

This is the checklist that separates "it runs on my machine" from "it runs safely in production."

  • Use small, specific base images (-slim, -alpine, or distroless) — smaller image, smaller attack surface.
  • Pin versions (node:20.11-slim, not node:latest) — reproducible builds, no surprises.
  • Order Dockerfile instructions least → most frequently changing, to maximize layer cache hits.
  • Add a .dockerignore so .git, node_modules, and secrets never enter the build context.
  • Don't run as root inside the container — add USER app in the Dockerfile.
  • Never bake secrets into an image layer; pass them at runtime as env vars or mounted secrets, and use BuildKit's --secret for build-time ones.
  • Use multi-stage builds to keep build tooling out of the final, shipped image.
  • Scan images for known CVEs (docker scout, Trivy, Grype) as part of CI.
Common mistake: mounting your whole home directory, or the Docker socket (-v /var/run/docker.sock:/var/run/docker.sock), into a container gives that container effective root on the host. Only do it when you genuinely mean to.
You made it. That's the whole course — from "what even is a container" to running multi-service stacks, debugging them at 2am, and locking them down properly. Take the quiz next, then move on to Kubernetes, where a lot of this vocabulary comes right back.