apt-get update in a separate RUN from apt-get install
Docker caches each RUN instruction separately. When apt-get update sits in its own RUN, its cached layer is reused on later builds, so a changed apt-get install line runs against an old package index. That can install outdated, vulnerable package versions or fail when the old index points at files the mirror no longer has. Run update and install in the same RUN.
openrouting — dockerfile explainer
$ explain Dockerfile! apt-get update is in a separate RUN from install mediumline 2fix: see below$
What the free Dockerfile explainer reports on the risky example below.
Why it matters
The build cache matches RUN instructions by their text. apt-get update never changes, so once cached it is never re-run, however old the index becomes.
When the install line changes (a new package, say), Docker re-runs only that step, against the stale index, which can pin you to old versions or cause 404 errors from the mirror.
The explainer flags an apt or apt-get update in a RUN that doesn't install, when a later RUN in the same stage does.
Risky and safer Dockerfile
RiskyDockerfile
FROM debian:12-slim
RUN apt-get update
RUN apt-get install -y --no-install-recommends ca-certificates
COPY app /usr/local/bin/app
USER 10001
HEALTHCHECK CMD ["/usr/local/bin/app", "health"]
CMD ["/usr/local/bin/app"]
SaferDockerfile
FROM debian:12-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY app /usr/local/bin/app
USER 10001
HEALTHCHECK CMD ["/usr/local/bin/app", "health"]
CMD ["/usr/local/bin/app"]
How to fix it
Put apt-get update and apt-get install in the same RUN, joined with &&.
Use --no-install-recommends to avoid pulling in packages you didn't ask for.
Remove the package lists in that same RUN (rm -rf /var/lib/apt/lists/*) so they don't add size to the layer.
When it's acceptable
Rarely. If you rebuild with --no-cache every time, the split doesn't go stale, but combining the steps costs nothing and keeps the image smaller.
Check your own Dockerfile
The risky example is loaded below. Paste your own file to check it for this and every other Dockerfile rule. It runs in your browser; nothing is uploaded.
Runs apt-get update while building the image and saves the result as a new layer.
Docker caches each instruction separately. Once the update layer is cached, later builds install from an old package index, which can mean old, vulnerable packages.
Safer: Run apt-get update, apt-get install --no-install-recommends and rm -rf /var/lib/apt/lists/* in a single RUN.
Sets the default command to /usr/local/bin/app. It runs when the container starts, and anything passed to docker run replaces it.
Questions
Why should apt-get update and install be in the same RUN?
So they are cached together. If update is a separate cached step, later builds install from an old package index.
Should I delete /var/lib/apt/lists in a Dockerfile?
Yes, in the same RUN as the install. The lists are only needed during installation, and removing them in a later RUN would not shrink the earlier layer.
Does this apply to apt as well as apt-get?
Yes. The explainer checks both apt update and apt-get update followed by an install in a later RUN of the same stage.