Чем отличает COPY от ADD
Инструкции COPY и ADD в Dockerfile предназначены для копирования файлов и директорий с хост-машины в образ, но ADD обладает дополнительными возможностями: автоматическим извлечением локальных tar-архивов и поддержкой URL-источников. Основное правило: для простого копирования используйте COPY, а ADD — только когда нужны его расширенные функции.
Как это работает
Обе инструкции имеют одинаковый синтаксис: COPY <источник> <назначение> и ADD <источник> <назначение>. Источник — путь к файлу или директории на хост-системе (относительно контекста сборки), назначение — путь внутри образа. Однако поведение различается:
COPYвыполняет только копирование. Это предсказуемая и прозрачная операция: что указали, то и скопируется.ADDдополнительно умеет:- распаковывать локальные архивы в форматах
tar,tar.gz,tar.bz2,tar.xz(при этом распаковка происходит автоматически, без дополнительных команд); - загружать файлы по URL (например,
ADD https://example.com/file.tar.gz /app/).
- распаковывать локальные архивы в форматах
Пример
Типичный Dockerfile с использованием обеих инструкций:
FROM ubuntu:22.04
# Простое копирование локального файла
COPY app.py /app/app.py
# Копирование директории
COPY ./config /app/config
# ADD с распаковкой локального архива
ADD bundle.tar.gz /app/bundle
# ADD с загрузкой по URL (не рекомендуется для продакшена)
ADD https://example.com/data.tar.gz /tmp/data.tar.gzВ первом случае COPY копирует файл и директорию как есть. Во втором ADD автоматически извлекает содержимое bundle.tar.gz в /app/bundle. В третьем — скачивает архив по URL, но не распаковывает его (распаковка URL-архивов не выполняется).
Подводные камни
- Кеширование слоёв:
COPYлучше кешируется, так как Docker сравнивает содержимое копируемых файлов. ДляADDс URL кеш часто сбрасывается, потому что содержимое удалённого файла может измениться, и Docker не может проверить его без загрузки. Это замедляет сборку. - Неожиданная распаковка:
ADDавтоматически распаковывает локальные архивы. Если вы хотели просто скопировать архив, он будет извлечён, что может привести к неожиданной структуре каталогов. - Безопасность: загрузка файлов по URL внутри
ADDвыполняется на этапе сборки, что может быть небезопасно (атака на цепочку поставок, неконтролируемое содержимое). Лучше скачивать файлы отдельно и копировать черезCOPY. - Рекомендации Docker: официальная документация и линтеры (например, hadolint) настоятельно рекомендуют использовать
COPYвсегда, когда нет явной необходимости в распаковке архивов или загрузке по URL.
Когда использовать
- Используйте
COPYдля всех обычных операций копирования файлов и директорий. Это делает Dockerfile более предсказуемым и ускоряет сборку за счёт кеширования. - Используйте
ADDтолько в двух случаях:- нужно автоматически распаковать локальный tar-архив внутри образа;
- требуется загрузить файл по URL непосредственно в образ (но лучше избегать этого из-за проблем с кешированием и безопасностью).
Коротко
COPY— простое копирование,ADD— копирование с дополнительными функциями (распаковка архивов, URL).- Для большинства задач выбирайте
COPY: он предсказуем и лучше кешируется. ADDиспользуйте только для распаковки локальных архивов или загрузки по URL, осознавая риски.- Помните:
ADDс URL не распаковывает архив, а только скачивает его.
Похожие вопросы
- Без какой инструкции не может существовать докер файл80%
- Чем отличается CMD от ENTRYPOINT в DockerFile66%
- Что такое DevOps66%
- Какие задачи выполнял с использованием Terraform60%
- Какой опыт работы с ansible46%
- Какие инструменты использовали46%
- Как по-твоему должен выглядеть идеальный pipeline CI/CD, что в нём должно быть что за чем идти46%
- В чём отличие Deployment от Delivery46%