В чем разница между COPY и ADD в Dockerfiles?
ADD
и COPY
– это две похожие инструкции Dockerfile
, которые позволяют добавлять содержимое к изображениям во время сборки. В то время как COPY
— это прямое копирование из источника в место назначения, ADD
включает дополнительные функции для работы с архивами и удаленными URL-адресами.
КОПИРОВАТЬ
COPY
— более простая из двух инструкций. Он принимает два аргумента, источник и пункт назначения:
COPY example.txt /example/dir/example.txt
Исходный путь будет скопирован с вашего хоста Docker в файловую систему контейнера. Созданный образ будет включать скопированный файл или каталог по указанному пути назначения.
COPY
работает со всеми файлами и каталогами, но исходные пути ограничены теми, которые находятся в вашем активном контексте сборки. Контекст устанавливается при запуске docker build
:
docker build . # OR docker build /path/to/context
Инструкция автоматически создает целевой каталог в контейнере, если он еще не существует. Если вы добавите завершающую косую черту (/
), Docker рассматривает место назначения как каталог и поместит в него исходный файл.
Вы можете использовать подстановочные знаки, такие как *.jpg
, в исходном пути назначения для соответствия набору файлов. Эти выражения будут проанализированы с помощью сопоставителя Go filepath
.
Скопированные файлы по умолчанию имеют UID и GID, равные 0. Это можно настроить с помощью необязательного флага --chown
, который принимает UID, GID и имена. Он запускает chown
для скопированных файлов, когда они находятся внутри контейнера:
COPY --chown=my-user:my-group example.txt /example.txt
COPY
также поддерживает флаг --from
. Это изменяет исходный путь, чтобы он ссылался на другой образ контейнера, а не на ваш локальный контекст сборки. Он также работает с многоэтапными сборками, чтобы извлекать артефакты, созданные на более ранних этапах сборки.
# Copies /usr/bin/composer from the composer:latest image COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Multi-stage build example # Stage 1: Copies example.scss from working directory into node:latest image # Stage 2: Copies example.css built in stage 1 into the final image (based on httpd:latest) FROM node:latest AS sass COPY example.scss . RUN npm install -g node-sass && node-sass example.scss example.css FROM httpd:latest COPY --from=sass /example.css example.css
Флаг --from
должен ссылаться на именованный этап, указанный ранее в Dockerfile
. Когда нет соответствующей стадии, Docker предполагает, что вместо этого вы ссылаетесь на изображение. Вы столкнетесь с ошибкой сборки, если изображение не может быть извлечено.
ДОБАВЛЯТЬ
ADD
имеет тот же синтаксис, что и COPY
, допуская исходный и конечный пути. Не поддерживается --from
, но вы можете использовать --chown
.
В отличие от COPY
, ADD
может загружать URL-адреса удаленных файлов. Указание общедоступного URL-адреса в качестве исходного пути загрузит этот файл и добавит его в образ контейнера. Время изменения целевого пути (mtime
) будет установлено равным значению заголовка Last-Modified
в ответе HTTP загрузки.
ADD
также может извлекать tar-архивы, включая архивы, сжатые с помощью gzip, bzip2 и xz. Указание совместимого архива в качестве исходного пути приведет к распаковке его содержимого в указанный каталог контейнера. Существующее содержимое каталога будет сохранено.
Обнаружение архива основано на фактическом содержимом файла, а не на имени или расширении файла. Вы можете использовать любой подлинный файл архива, не называя его .tar
, .tar.gz
или .tar.xz
.
Возможность автоматического извлечения архивов упрощает добавление программных пакетов, распространяемых в виде tar-файлов, в ваши образы контейнеров. Указание пути tar для COPY
приведет к копированию сжатого файла архива как есть, а не его содержимого. Вам нужно будет использовать инструкцию RUN
, чтобы вручную распаковать файл.
Поведение вокруг COPY
применяется к ADD
в. За исключением удаленных URL-адресов, исходные пути должны существовать в контексте сборки. Путь назначения контейнера будет автоматически создан, если он не существует, с использованием правил Docker для разрешения пути.
Краткое содержание
COPY
и ADD
— это две тесно связанные, но совершенно разные инструкции, которые вы можете использовать при написании Dockerfile
. Поскольку их наборы функций перекрываются, вам может быть интересно, какой из них «лучше» использовать по умолчанию.
Согласно собственному руководству Docker по лучшим практикам, вы должны использовать COPY
, если вам не нужны дополнительные возможности ADD
. ADD
— непрозрачная операция, добавляющая магии в процесс копирования.
Использование ADD
только тогда, когда это действительно необходимо, помогает сообщить о ваших намерениях. В противном случае вы рискуете заставить членов команды использовать ADD
, что может привести к катастрофическим последствиям. Непреднамеренное ADD my-archive.tar .
вместо COPY my-archive.tar
может привести к путанице и нарушению сборки, когда содержимое архива отображается в вашем контейнере вместо сам архив.
Вы также должны тщательно обдумать, когда уместно использовать ADD
с удаленными URL-адресами. Более эффективно использовать curl
или wget
с инструкцией RUN
, так как это упрощает кэширование слоя изображения. Инструкция ADD
всегда делает кэш недействительным для всех последующих этапов сборки при изменении файла по удаленному URL-адресу.
По возможности рекомендуется удалять скопированные файлы после их использования. Если вы загружаете или извлекаете установщик программного обеспечения, удаление одноразового двоичного файла после его запуска поможет уменьшить размер окончательного образа.