Disable cache for specific RUN commands
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Docker does not provide a built-in RUN --no-cache switch that disables cache for one instruction while preserving cache for everything else. The real way to refresh one RUN step is to invalidate the cache for that layer intentionally, usually with a targeted build argument or by restructuring the Dockerfile so the unstable step has a narrow blast radius.
How Docker Layer Caching Actually Works
Each Dockerfile instruction produces a layer. Docker decides whether that layer can be reused by comparing the instruction and the state of earlier layers.
That means cache behavior is not controlled by a per-command runtime flag. It is controlled by whether Docker considers the inputs to that instruction unchanged.
The practical consequence is:
- if a layer is unchanged, Docker reuses it
- if a layer changes, Docker rebuilds it and every layer after it
So the question is really not "how do I disable cache for one RUN" but "how do I invalidate exactly the layer I want."
The Standard Technique: Cache-Busting Build Arguments
A small ARG referenced only in the target step is the usual solution.
Then build with a changing value when you want that step refreshed.
This invalidates the RUN that references CACHE_BUST and every layer after it, while still preserving earlier cached layers.
Keep the Invalidated Region Small
Because invalidating one layer also invalidates everything after it, layer ordering matters.
A good Dockerfile layout is:
- stable setup steps first
- unstable fetch or update step later
- as few layers after it as possible
That way, refreshing one network-dependent command does not force an unnecessary rebuild of half the image.
Common Case: Refreshing Package Metadata
A lot of people ask this question because package metadata becomes stale inside a cached layer. A targeted cache bust can help.
This works, but there is a tradeoff: if you refresh the package index frequently without pinning versions, builds become less reproducible.
So cache busting solves freshness, but it can reduce determinism if the downloaded package versions drift.
BuildKit Gives Better Tools in Some Cases
With BuildKit enabled, cache mounts can be a more precise approach than crude busting for package-manager workflows.
This still does not mean "no cache for one RUN" in the literal sense, but it does give you much finer control over what state persists across builds.
Prefer Explicit Inputs When Possible
If the step downloads an artifact, the strongest pattern is often to make the version an explicit build input instead of forcing a refresh every time.
Now the layer only changes when the tool version changes. That is usually better than time-based invalidation if reproducibility matters.
Common Pitfalls
Looking for a special Dockerfile flag to disable cache for exactly one RUN is the most common misconception. Standard Dockerfile syntax does not work that way.
Using a changing value such as a timestamp too early in the Dockerfile can trigger large unnecessary rebuilds.
Refreshing package-manager layers without pinning versions can make builds harder to reproduce.
Finally, remember that invalidating one layer also invalidates every later layer, so placement is as important as the cache-busting mechanism itself.
Summary
- Docker has no dedicated per-
RUNno-cache flag in ordinary Dockerfile syntax - the normal solution is to invalidate one layer intentionally with a targeted build input
- '
ARG-based cache busting is the simplest way to refresh a specific step' - put unstable steps as late as practical to limit rebuild cost
- for dependency-heavy builds, BuildKit cache mounts and explicit versioned inputs are often better than blanket cache busting

