Linting Best Practices
Treat the Dockerfile and its image as first-class source code that earns the same review rigor as your application.
Search across all documentation pages
Treat the Dockerfile and its image as first-class source code that earns the same review rigor as your application.
This list gathers the practices that keep linting and image testing fast, honest, and enforceable across a growing fleet.
Work top to bottom on a new repo, or pick the group that matches your current gap on an existing one.
Each practice is a bold rule followed by the reasoning, so you can lift the rule into a review checklist or a CODEOWNERS conversation.
Treat security and correctness practices as blocking gates and efficiency practices as thresholds you tighten over time.
error or warning deliberately with --failure-threshold rather than accepting the default, and tighten it as the codebase cleans up..hadolint.yaml. Encode the team's standing exceptions and thresholds in the repo so the policy is versioned and reviewable, not tribal knowledge.# hadolint ignore=DLxxxx for a single instruction and leave a comment explaining why it is safe, so reviewers see the exception in the diff.override.error to make rules like "never use :latest" hard failures rather than warnings.trustedRegistries so a build that pulls from an unapproved source fails at lint time.FROM image:tag@sha256:... so every build and later scan or signature applies to the exact same bits.apt-get install with rm -rf /var/lib/apt/lists/* in one RUN so the cache never ships and rebuilds stay reproducible..dockerignore. Exclude .git, node_modules, and test fixtures so those bytes never enter the build context or a layer..dive-ci policy with an efficiency floor and a wasted-bytes ceiling so regressions in image layout fail the pipeline.runAsNonRoot will hold, since a base image can silently reset USER to root./healthz path your Kubernetes readiness probe uses, so the test exercises the code the platform depends on.--exit-code 1 --severity HIGH,CRITICAL so known-vulnerable images cannot be promoted.You should have linting, efficiency, structure, smoke, and scanning gates running in order on every image, each with an owned threshold.
Exceptions should live in checked-in config with justifications, not scattered ad hoc suppressions.
The same digest should flow from build through scan and signature to deployment, with a cluster admission policy as the final backstop.
Which gates should block merge versus warn? Security and correctness gates block; efficiency thresholds can start as warnings and harden as the fleet cleans up.
How do I stop linting from being ignored? Keep it fast, keep exceptions justified in-repo, and make the check required in branch protection.
Do I need all six groups on day one? No - start with linting and a smoke test, then layer in efficiency, structure, and supply-chain gates as you scale.
Why gate by digest instead of tag? Tags move and digests do not, so gating by digest guarantees you test and ship the identical artifact.
Is a Docker smoke test enough before Kubernetes? It catches startup failures early, but pair it with a kubectl rollout status check because nodes run containerd, not Docker.
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026