Layer Order Matters
Docker caches layers. Put instructions that change rarely (installing system packages) before instructions that change often (copying your source code). A single cache miss invalidates all subsequent layers.
Multi-Stage Builds
Build in one stage, copy only the artefact into a minimal runtime image. A Go binary built in a full Go SDK image can run in a 5MB scratch container with zero attack surface.
Never Run as Root
Create a non-root user and switch to it before the CMD instruction. If your container is compromised, the attacker gets an unprivileged user, not root.
.dockerignore is Not Optional
Exclude node_modules, .git, *.env, and any file you wouldn't commit to version control. Without it, Docker's build context ships your entire working directory to the daemon.