Поиск по сайту:

В чем разница между 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-адресу.

По возможности рекомендуется удалять скопированные файлы после их использования. Если вы загружаете или извлекаете установщик программного обеспечения, удаление одноразового двоичного файла после его запуска поможет уменьшить размер окончательного образа.