Cloud Native 19 min read

Master Dockerfile Caching and Multi‑Stage Build Best Practices

This guide explains how Docker builds images layer by layer, how caching works, when it invalidates, and provides practical tips such as ordering instructions, using multi‑stage builds, proper tagging, exposing ports, and best practices for each Dockerfile directive to create lean, maintainable containers.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Master Dockerfile Caching and Multi‑Stage Build Best Practices

During image construction Docker executes each Dockerfile instruction in order, committing the result as a new image layer; before running a step Docker checks its cache for a reusable layer and skips rebuilding if the instruction and its context match.

Building Cache

To maximize cache reuse, keep the Dockerfile stable and modify it near the end. Changing the MAINTAINER instruction forces Docker to re‑run subsequent RUN steps, breaking the cache. To disable caching entirely, add --no-cache=true to docker build.

Docker starts from the base image specified by FROM and matches each subsequent instruction against the child images created from that base. If any instruction differs, the cache is invalidated.

Usually a single child image is enough for comparison, though some instructions need deeper checks.

For ADD and COPY, Docker also hashes the contents of the referenced files; any change in those files invalidates the cache.

File changes caused by RUN apt-get -y update are not considered for cache matching, so the cache remains valid for those layers.

Once the cache is broken, all following instructions generate new layers without reuse.

Using Multi‑Stage Builds

Multi‑stage builds dramatically reduce final image size by discarding intermediate layers. Order stages from low‑frequency changes to high‑frequency changes to keep caches reusable.

FROM golang:1.11-alpine AS build
# install build tools
RUN apk add --no-cache git
RUN go get github.com/golang/dep/cmd/dep
COPY Gopkg.lock Gopkg.toml /go/src/project/
WORKDIR /go/src/project/
RUN dep ensure -vendor-only
COPY . /go/src/project/
RUN go build -o /bin/project
FROM scratch
COPY --from=build /bin/project /bin/project
ENTRYPOINT ["/bin/project"]
CMD ["--help"]

Using Tags

Tag images with -t during docker build to create readable identifiers, e.g. docker build -t="tuxknight/luckypython" ..

Exposing Ports

Declare container ports with EXPOSE (e.g., EXPOSE 80). The directive only documents the port; actual host‑to‑container mapping is done with -p or -P at docker run time.

CMD and ENTRYPOINT Syntax

CMD

and ENTRYPOINT each support exec‑form ( ["executable","param"]) and shell‑form. Exec‑form avoids the implicit /bin/sh -c wrapper and yields predictable execution. Use CMD for default arguments and ENTRYPOINT for the immutable command.

Containers Are Ephemeral

Containers run as processes, not full machines; they start on demand and can be removed and recreated, keeping configuration minimal.

.dockerignore File

Use a .dockerignore file to exclude unnecessary files from the build context, speeding up builds.

Avoid Upgrading Versions in Build

Prefer updating the base image rather than running package upgrades inside the container.

Application Decoupling

Run a single process per container and separate concerns (web, database, cache) into distinct containers; use Docker networking to connect them.

Minimizing Image Layers

Only RUN, COPY, and ADD create layers; other instructions generate temporary images without increasing size.

Multi‑stage builds let you copy only the final artifacts, keeping intermediate tooling out of the final image.

Avoid Installing Unnecessary Packages

Limit installed packages to those required for the application to reduce size and attack surface.

Use Specific Tags

Always specify a full repository name and tag in FROM, e.g., FROM debian:jessie, rather than an untagged FROM debian.

Sort Multi‑Line Parameters

Alphabetically sort long RUN lines and add a space before the backslash for readability.

RUN apt-get update && apt-get install -y \
  bzr \
  cvs \
  git \
  mercurial \
  subversion

Dockerfile Instruction Best Practices

FROM

Prefer official images such as Debian (≈100 MB) or Alpine (<5 MB) as the base.

LABEL

Use LABEL to add metadata; multiple labels can be combined with line continuations.

# Set one or more individual labels
LABEL com.example.version="0.0.1-beta"
LABEL vendor="ACME Incorporated"
LABEL com.example.release-date="2015-02-12"

RUN

Chain apt-get update and apt-get install in a single RUN to avoid stale caches (cache busting). Split long commands with backslashes for readability.

RUN apt-get update && apt-get install -y \
    aufs-tools \
    automake \
    btrfs-tools \
    build-essential \
    curl \
    git

EXPOSE

Declare the ports the container will listen on, e.g., EXPOSE 80 for a web server.

ENV

Set environment variables such as ENV PATH /usr/local/nginx/bin:$PATH to configure runtime behavior.

CMD

Use the exec‑form CMD ["executable","param1","param2"] for reliable defaults.

ENTRYPOINT

Define the immutable command with exec‑form ENTRYPOINT ["executable","param1"]; combine with CMD for default arguments.

ADD and COPY

Prefer COPY for straightforward file transfers; reserve ADD for extracting tarballs or remote URLs.

VOLUME

Declare persistent directories with VOLUME to enable data sharing between containers or the host.

USER

Run containers as non‑root users with USER; avoid sudo inside containers.

WORKDIR

Use absolute paths with WORKDIR instead of chaining RUN cd … && … for clarity and maintainability.

Cachingbest practicesDockerfileMulti‑stage
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.