Dockerfile Practices are a DevOps Tax Before They are a Security Concern
Dockerfiles accumulate technical debt quietly and continuously across engineering teams, through individually rational decisions made under deadline pressure that compound into structural problems nobody planned for and nobody owns.
It’s usually a developer who inherits a base image that works, adds dependencies inline without thinking about layer ordering, copies the entire source directory before the package manager runs and ships something that builds and deploys correctly enough that nobody questions. But that’s only until the build times start climbing or the image sizes start inflating or the pipeline starts behaving differently across environments for reasons that take two days to diagnose.
Multiply this pattern across dozens of services, built by different developers, at different times, with different habits and different levels of container expertise. The result is an organization whose Dockerfile practices are as varied as the engineers who wrote them, where layer caching is inconsistent, base images are unpinned, dependency installation is unordered and the build artifacts landing in production registries range from lean and reproducible to bloated and opaque, without any governance mechanism explaining why.
“That is the state of Dockerfile quality in most engineering organizations today,” says Advait Patel, senior site reliability engineer at Broadcom, notable author and Docker Captain. “It is a DevOps problem,” he adds, “with measurable costs in build time, infrastructure spend, deployment velocity and cross-environment reproducibility that most teams are not attributing to its root cause.” This is because the Dockerfile has historically been treated as a disposable script rather than as a production artifact that shapes every downstream outcome in the container delivery pipeline. Patel built DockSec, an open-source container security and optimization tool and the OWASP Incubator Project, specifically to close that gap, starting with the Dockerfile as the earliest intervention point in the container delivery process.
How DockSec Came From a Different Problem Entirely
Advait Patel did not set out to build a Dockerfile optimization tool when he started work on DockSec. It started with a production incident in late 2024, where a vulnerable base image sat unactioned at item 31 of a 237 CVE security report because the tooling that detected the vulnerability produced an output that no developer on the team had the context or the workflow capacity to act on, and the scanner had done its job correctly while the container security triage infrastructure around it had failed. However, the engineering work Patel did in response to that incident produced something with a broader DevOps value proposition than the security framing alone captures.
DockSec integrates Trivy for CVE detection, Hadolint for Dockerfile analysis and Docker Scout for dependency scanning, and applies an AI layer to correlate findings, weight them by actual deployment context and produce plain language remediation guidance that a developer without deep container security expertise can act on directly. But the Hadolint integration in particular means DockSec reviews Dockerfile quality in the DevOps sense, surfacing inefficient build patterns, inconsistent layer ordering, unnecessary dependencies and structural anti-patterns that slow pipelines and reduce reproducibility before they become security problems or operational failures.
“In many teams, Dockerfiles evolve quickly and often become messy over time, and that messiness compounds silently until it surfaces as a build failure, a pipeline inconsistency or an image size problem that nobody can trace back to a specific decision,” Patel explains. “DockSec reviews the Dockerfile and highlights areas where the build process can be simplified, standardized and optimized so that it fits better into automated CI/CD pipelines, and that optimization work is as much a DevOps discipline problem as it is a security one.”
The Dockerfile is a production artifact that shapes every downstream outcome in the container delivery pipeline, and most organizations are governing it less carefully than they govern a pull request description.
Build Consistency as a First-Order DevOps Principle
The most immediate and measurable consequence of poor Dockerfile discipline is build across environments, and it manifests in ways that waste engineering time at a rate that most organizations are not measuring directly because the cost shows up as debugging overhead rather than as a line item in the infrastructure budget. When a container behaves differently in development than it does in CI and differently in CI than it does in production, the root cause is almost always in the Dockerfile, in an unpinned base image that pulled a different upstream version between builds, in a RUN command that produces different outputs depending on the network state at build time or in a dependency installation step that resolves to different package versions across environments because nobody pinned the versions explicitly.
“When Dockerfiles follow predictable patterns with structured build steps and cleaner dependency installation practices, builds become more reproducible across different environments — and that reproducibility is a foundational DevOps principle that Dockerfile inconsistency quietly undermines every time a developer ships something that works locally and fails in CI for reasons that take half a day to diagnose,” Patel explains. “DockSec encourages developers to use predictable base images, structured build steps and cleaner dependency installation practices precisely because those practices are the foundation of reproducible builds, and reproducible builds are the foundation of everything else in a reliable delivery pipeline.”
Andrian Budantsov, CEO and founder of Hypersequent (QA Sphere), saw the reproducibility problem play out in concrete terms across a SaaS platform running multiple containerized back-end microservices through a GitHub Actions pipeline inside a Turborepo monorepo. “While catastrophic deployment failures were rare, we repeatedly hit subtle works-locally, fails-in CI issues from unpinned bases, inconsistent RUN ordering or missing flags like –no-install-recommends,” he explains. “Each cost 0.5–2 engineer-days to diagnose and fix, which is a meaningful overhead when it happens regularly across multiple services and multiple teams.”
What Poor Layer Caching Actually Costs
The layer caching problem is where Dockerfile quality most directly translates into pipeline cost, and it is also the problem most consistently misunderstood by developers who have not been taught how Docker’s build cache actually works. Docker caches each layer in a Dockerfile and reuses cached layers on subsequent builds as long as the layer and everything above it in the file have not changed. When developers place dependency installation steps after source code copy steps, any change to the source code invalidates the dependency layer, forcing the package manager to re-run on every build, even when the dependencies themselves have not changed. This ordering mistake, which is easy to make and easy to miss in code review, is responsible for a disproportionate share of the long build times that teams attribute to CI infrastructure rather than to Dockerfile structure.
Budantsov measured the cost of that pattern directly across Hypersequent’s service fleet. “Developers frequently used heavy base images, installed system dependencies late and copied the entire source directory before running package managers, resulting in images ranging from 1.6 GB to 2.3 GB, when optimized versions should have been 400–600 MB,” Budantsov notes. “CI builds routinely took 12–16 minutes per service, and we calculated roughly $300 per month in extra registry storage and bandwidth costs from the oversized images. The worst pain was when any change to a lower layer invalidated the entire cache. We once had a core service stuck at 22-minute builds for two full days, blocking the whole team.”
The fix that Budantsov’s team applied was architectural rather than incremental, requiring a fundamental redesign of how layers, caching and dependencies were ordered across the entire service fleet. Moving to mandatory multi-stage builds, enforcing dependency-before-source-code layer ordering, adding comprehensive .dockerignore files and pinning base image tags delivered an immediate 30% reduction in average build times across the fleet. A second wave of optimization, aligning Docker layer cache, Turborepo task cache and GitHub Actions cache through explicit cache key design and –cache-from and –cache-to directives, added a further 43% improvement, bringing most services from 12–16-minute builds down to 3.5–4.5 minutes. Image sizes dropped 60–75% across the board.
“Large or poorly structured Dockerfiles slow down builds, increase image sizes and make deployments slower in ways that accumulate gradually enough that teams often do not realize how much pipeline capacity they are losing until they measure it,” Patel argues. “DockSec identifies inefficient build patterns and suggests improvements like reducing unnecessary layers, removing redundant dependencies and restructuring build commands, and those suggestions translate directly into faster pipelines, smaller artifacts and lower infrastructure costs at the registry and runtime layers.”
The Standardization Problem in Large Engineering Organizations
Build time and image size are measurable problems with measurable solutions, and most engineering organizations eventually address them when the pain becomes obvious enough. The standardization problem is harder to measure and to solve because it is fundamentally an organizational problem rather than a technical one, and its costs show up in code review overhead, onboarding friction and the accumulated cognitive load of working across a service fleet where every Dockerfile was written by a different developer following different conventions that nobody ever formalized.
“Over time, Dockerfiles written by different developers across the same organization become inconsistent in ways that make them harder to understand, review and maintain — and that inconsistency becomes especially costly in large engineering organizations, where many services are built and deployed independently without any central visibility into what patterns are being followed or ignored,” Patel explains. “DockSec helps standardize how Dockerfiles are written across teams, which makes them easier to understand, review and maintain, and that standardization becomes the foundation for everything else, because you cannot automate what you cannot predict and you cannot govern what you cannot read.”
Budantsov found that the standardization challenge was as much a cultural problem as a technical one, and that the approach to overcoming it mattered as much as the solution itself. Avoiding top-down Dockerfile standards documents, and instead, embedding quality feedback directly into the pull request review process turned out to be the decision that made adoption stick. Every PR received explicit Dockerfile comments tied to real examples from the team’s own slowest builds, and a few 30-minute internal demos showing concrete before-and-after build times made the case more effectively than any policy document could have.
“Initial resistance was real,” Budantsov notes. “It builds locally, why touch it? is common across developers. After the first wave of fixes, average build times dropped 30%. Once people saw their own PRs finish in 4 minutes instead of 14, adoption became organic and within three months it became muscle memory — developers now fixing caching issues before even opening the PR.”
Automated Quality Gates and the AI Layer
The organizational adoption challenge that Budantsov describes, moving from developer resistance to muscle memory in three months, was partly a cultural outcome and partly an infrastructure outcome and the infrastructure piece was automated quality gates running on every pull request before human reviewers engaged. Hadolint running in GitHub Actions in under 10 seconds, failing builds on critical issues including the latest tags, missing USER directives, inefficient apt-get patterns and exposed ports without justification, gave the standardization effort an enforcement mechanism that policy documents cannot provide, and code review alone cannot scale to cover across a large service fleet.
Budantsov added an AI-assisted review layer on top of the static linting, running the Claude Code GitHub Action automatically on every pull request to analyze changes and post targeted inline review comments directly in the PR discussion before human reviewers engaged. The combination of Hadolint static analysis and AI-powered review catches approximately 90% of common anti-patterns automatically, and the educational effect of the inline comments, explaining not just what to fix but why the fix matters in terms of cache behavior and image size, results in developers writing cleaner Dockerfiles from the start rather than learning through failure.
“DockSec helps shift container building from an ad hoc process to a more structured DevOps practice by improving Dockerfile quality early in development, which means teams build containers that integrate more smoothly with automation, scale better in container platforms and remain easier to maintain over the long term,” Patel argues. “The AI layer matters because it brings the translation capability, turning Hadolint findings into plain-language guidance that a developer without deep container expertise can act on directly, and that translation is exactly the gap that most Dockerfile quality tooling leaves open.”
The combination that Budantsov describes at Hypersequent — Hadolint for static enforcement and AI-assisted review for educational feedback — mirrors the design philosophy behind DockSec at the workflow integration level. Both approaches treat the pull request as the intervention point where Dockerfile quality can be shaped before it enters the build pipeline rather than being diagnosed after it has already slowed the build or inflated the image or introduced a vulnerability that propagated into a production deployment.
What Treating Dockerfiles as Production Artifacts Actually Requires
Budantsov’s advice for organizations currently treating Dockerfile quality as an afterthought is direct and grounded in the cost data his team generated before and after the optimization work. Stop treating Dockerfiles as disposable scripts and start treating them as production artifacts that directly control CI minutes, cloud bills, deployment speed, security posture and developer velocity daily. Add automated quality gates immediately, enforce multi-stage builds and dependency-before-source-code ordering as non-negotiable patterns, track build time and image size metrics before and after each change and use those numbers to make the case internally, because numbers destroy resistance faster than any policy document.
Patel’s framing of what DockSec is trying to accomplish at the community level adds the dimension that the organizational optimization conversation often misses, which is that the teams most exposed to the costs of poor Dockerfile quality are frequently the teams least positioned to access the enterprise tooling that addresses it. DockSec is an OWASP Incubator Project with over 13,000 downloads across more than 40 countries, and the reach of that adoption reflects a gap in the commercial tooling market where the organizations that need better Dockerfile discipline the most are the ones that cannot afford the enterprise security platforms that nominally provide it.
“By improving Dockerfile quality early in development, teams can build containers that integrate more smoothly with automation, scale better in container platforms and remain easier to maintain over the long term — and that outcome is as much a DevOps outcome as it is a security outcome,” Patel argues. “The organizations that treat those two things as the same problem, rather than routing them through separate teams with separate tools and separate review processes, are the ones that get both right without doubling the overhead.”


