mirror of https://github.com/docker/docs.git
Merge pull request #18582 from dvdksn/add-bestpractice
build: refresh ADD and COPY recommendations
This commit is contained in:
commit
80e57e64a6
|
|
@ -302,53 +302,62 @@ For more information about `ENV`, see [Dockerfile reference for the ENV instruct
|
||||||
|
|
||||||
### ADD or COPY
|
### ADD or COPY
|
||||||
|
|
||||||
Although `ADD` and `COPY` are functionally similar, generally speaking, `COPY`
|
`ADD` and `COPY` are functionally similar. `COPY` supports basic copying of
|
||||||
is preferred. That’s because it’s more transparent than `ADD`. `COPY` only
|
files into the container, from the [build context](../../build/building/context.md)
|
||||||
supports the basic copying of local files into the container, while `ADD` has
|
or from a stage in a [multi-stage build](../../build/building/multi-stage.md).
|
||||||
some features (like local-only tar extraction and remote URL support) that are
|
`ADD` supports features for fetching files from remote HTTPS and Git URLs, and
|
||||||
not immediately obvious. Consequently, the best use for `ADD` is local tar file
|
extracting tar files automatically when adding files from the build context.
|
||||||
auto-extraction into the image, as in `ADD rootfs.tar.xz /`.
|
|
||||||
|
|
||||||
If you have multiple Dockerfile steps that use different files from your
|
You'll mostly want to use `COPY` for copying files from one stage to another in
|
||||||
context, `COPY` them individually, rather than all at once. If
|
a multi-stage build. If you need to add files from the build context to the
|
||||||
a specifically required file changes, then this ensures that
|
container temporarily to execute a `RUN` instruction, you can often substitute
|
||||||
only that step's build cache is invalidated, forcing only that step to be run again.
|
the `COPY` instruction with a bind mount instead. For example, to temporarily
|
||||||
|
add a `requirements.txt` file for a `RUN pip install` instruction:
|
||||||
For example:
|
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
COPY requirements.txt /tmp/
|
RUN --mount=type=bind,source=requirements.txt,target=/tmp/requirements.txt \
|
||||||
RUN pip install --requirement /tmp/requirements.txt
|
pip install --requirement /tmp/requirements.txt
|
||||||
COPY . /tmp/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Results in fewer cache invalidations for the `RUN` step, than if you put the
|
Bind mounts are more efficient than `COPY` for including files from the build
|
||||||
`COPY . /tmp/` before it.
|
context in the container. Note that bind-mounted files are only added
|
||||||
|
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`.
|
||||||
|
|
||||||
Because image size matters, using `ADD` to fetch packages from remote URLs is
|
The `ADD` instruction is best for when you need to download a remote artifact
|
||||||
strongly discouraged; you should use `curl` or `wget` instead. That way you can
|
as part of your build. `ADD` is better than manually adding files using
|
||||||
delete the files you no longer need after they've been extracted and you don't
|
something like `wget` and `tar`, because it ensures a more precise build cache.
|
||||||
have to add another layer in your image. For example, you should avoid doing
|
`ADD` also has built-in support for checksum validation of the remote
|
||||||
things like:
|
resources, and a protocol for parsing branches, tags, and subdirectories from
|
||||||
|
[Git URLs](../../engine/reference/commandline/build.md#git-repositories).
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
ADD https://example.com/big.tar.xz /usr/src/things/
|
# syntax=docker/dockerfile:1
|
||||||
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
|
|
||||||
RUN make -C /usr/src/things all
|
FROM scratch AS src
|
||||||
|
ARG DOTNET_VERSION=8.0.0-preview.6.23329.7
|
||||||
|
ADD --checksum=sha256:270d731bd08040c6a3228115de1f74b91cf441c584139ff8f8f6503447cebdbb \
|
||||||
|
https://dotnetcli.azureedge.net/dotnet/Runtime/$DOTNET_VERSION/dotnet-runtime-$DOTNET_VERSION-linux-arm64.tar.gz /dotnet.tar.gz
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0.0-preview.6-bookworm-slim-arm64v8 AS installer
|
||||||
|
|
||||||
|
# Retrieve .NET Runtime
|
||||||
|
RUN --mount=from=src,target=/src <<EOF
|
||||||
|
mkdir -p /dotnet
|
||||||
|
tar -oxzf /src/dotnet.tar.gz -C /dotnet
|
||||||
|
EOF
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0.0-preview.6-bookworm-slim-arm64v8
|
||||||
|
|
||||||
|
COPY --from=installer /dotnet /usr/share/dotnet
|
||||||
|
RUN ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
|
||||||
```
|
```
|
||||||
|
|
||||||
And instead, do something like:
|
|
||||||
|
|
||||||
```dockerfile
|
|
||||||
RUN mkdir -p /usr/src/things \
|
|
||||||
&& curl -SL https://example.com/big.tar.xz \
|
|
||||||
| tar -xJC /usr/src/things \
|
|
||||||
&& make -C /usr/src/things all
|
|
||||||
```
|
|
||||||
|
|
||||||
For other items, like files and directories, that don't require the tar
|
|
||||||
auto-extraction capability of `ADD`, you should always use `COPY`.
|
|
||||||
|
|
||||||
For more information about `ADD` or `COPY`, see the following:
|
For more information about `ADD` or `COPY`, see the following:
|
||||||
- [Dockerfile reference for the ADD instruction](../../engine/reference/builder.md#add)
|
- [Dockerfile reference for the ADD instruction](../../engine/reference/builder.md#add)
|
||||||
- [Dockerfile reference for the COPY instruction](../../engine/reference/builder.md#copy)
|
- [Dockerfile reference for the COPY instruction](../../engine/reference/builder.md#copy)
|
||||||
|
|
@ -518,4 +527,4 @@ fails catastrophically if the new build's context is missing the resource being
|
||||||
added. Adding a separate tag, as recommended above, helps mitigate this by
|
added. Adding a separate tag, as recommended above, helps mitigate this by
|
||||||
allowing the Dockerfile author to make a choice.
|
allowing the Dockerfile author to make a choice.
|
||||||
|
|
||||||
For more information about `ONBUILD`, see [Dockerfile reference for the ONBUILD instruction](../../engine/reference/builder.md#onbuild).
|
For more information about `ONBUILD`, see [Dockerfile reference for the ONBUILD instruction](../../engine/reference/builder.md#onbuild).
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue