Skip to content

update best practices #22169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion content/manuals/build/building/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -600,13 +600,31 @@ temporarily for a single `RUN` instruction, and don't persist in the final
image. If you need to include files from the build context in the final image,
use `COPY`.

#### ADD or `curl`/`wget` and equivalents

The `ADD` instruction is best for when you need to download a remote artifact
as part of your build. `ADD` is better than manually adding files using
as part of your build.

`ADD` is better than manually adding files using
something like `wget` and `tar`, because it ensures a more precise build cache.
`ADD` also has built-in support for checksum validation of the remote
resources, and a protocol for parsing branches, tags, and subdirectories from
[Git URLs](/reference/cli/docker/buildx/build.md#git-repositories).

> [!NOTE]
>
> `ADD` redownloads the file (or uses a HEAD request with [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)s
> if the remote server supports it) every time the image is built to verify the checksum
> and monitor changes to bust the cache whereas the `RUN curl` equivalent only busts
> the cache and redownloads the file when the process arguments change
> (e.g. the URL in the curl command is changed).
> This may be significant if the file to be downloaded is large.

If the file being downloaded is supposed to be part of the image and is okay to be redownloaded on each build (to verify changes), using `ADD` as part of the image build is more suitable.

If the file is an archive being extracted, or not supposed to be part of the final image, using `ADD` by itself would add an additional layer and subsequently removing it using `RUN rm` will not decrease the image size. In this case, look at the below example to use a multi stage build with a `scratch` image to download the file using `ADD` and bind mounting it where needed in the final image.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how "supposed to be part of final image" matters in here. Layers in the target stage end up in the exported image, and RUN rm does not release data from the parent layers. This is true for all instructions and nothing specific about ADD or RUN.

Copy link
Author

@adyanth adyanth Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was to clarify that always using ADD in your image build process is not the recommendation, since it adds a layer when you might not want one, which is how saying ADD is always better than curl/wget in the best practice reads to me. Is there a better way to phrase that using ADD without a multi stage build to bring it in when the artifact is not needed in the final image is not a best practice?

* Same note from above applies regarding file sizes and redownloads.

The following example uses `ADD` to download a .NET installer. Combined with
multi-stage builds, only the .NET runtime remains in the final stage, no
intermediate files.
Expand Down