RUN package-manager update instruction alone

ID

orphan_package_update

Severity

high

Family

Container Security

Tags

cache-busting, correctness, dockerfile

Description

Always combine RUN <package-manager> update with a following <package-manager> install in the same RUN statement.

Security

N/A

Examples

Using <package-manager> update alone in a RUN statement causes caching issues and subsequent install instructions to fail. An example with apt-get package manager follows:

FROM ubuntu:22.04
# ...
# Issue: separate update and install in separate RUN instructions
RUN apt-get update
RUN apt-get install -y curl

After building the image, all layers are in the Docker cache. Suppose you later modify install by adding an extra package as shown:

FROM ubuntu:22.04
# ...
# Issue: separate update and install in separate RUN instructions
RUN apt-get update
RUN apt-get install -y curl nginx

Docker sees update instructions in the initial and modified dockerfiles as identical, and reuses the cache from previous steps. As a result the apt-get update isn’t executed because the build uses the cached version. Because the apt-get update isn’t run, your build can potentially get an outdated version of the curl and nginx packages.

Using RUN apt-get update && apt-get install -y <packages> ensures your Dockerfile installs the latest package versions with no further coding or manual intervention. Invalidating the layer’s cache when needed is known as cache busting. You can also achieve cache busting by specifying a package version. This is known as version pinning, like in:

RUN apt-get update && apt-get install -y \
  package-bar \
  package-baz \
  package-foo=1.3.* \
  && apt-get clean

Please note that the package manager’s cache is also cleaned up with apt-get clean. Do not confuse the Docker layers cache with the packages' cache held by the package manager !

Mitigation / Fix

Combine <package-manager> update and <package-manager> install instructions into a single one.