В чем разница между инструкциями COPY и ADD в Dockerfile?

Ответ

Обе инструкции, COPY и ADD, служат для копирования файлов и директорий в образ Docker, но имеют ключевые различия в функциональности.

Сравнение COPY и ADD

ИнструкцияИсточникКлючевая особенность
COPYЛокальные файлы/директорииПростое и предсказуемое копирование.
ADDЛокальные файлы/директории, URL, tar-архивыОбладает «магией»: может скачивать файлы по URL и автоматически распаковывать локальные .tar архивы.

Примеры:

# Dockerfile

# COPY: Просто копирует локальную директорию app в образ
COPY ./app /usr/src/app

# ADD: Копирует и распаковывает локальный архив
ADD project.tar.gz /usr/src/project

# ADD: Скачивает файл по URL (без распаковки)
ADD https://example.com/config.json /etc/config.json

Рекомендация и лучшая практика

Всегда используйте COPY, если вам не нужна специфическая функциональность ADD.

Почему COPY предпочтительнее?

  1. Предсказуемость: COPY делает только одно — копирует. Это делает Dockerfile более понятным и прозрачным.
  2. Кэширование: ADD с URL может приводить к проблемам с кэшированием слоев. Docker не скачивает файл заново, если URL не изменился, но содержимое файла по этому URL могло измениться. Это делает сборки ненадежными. Для скачивания файлов лучше использовать RUN wget или RUN curl, так как это создает отдельный кэшируемый слой и позволяет управлять процессом (например, проверять checksum).
  3. Безопасность: Автоматическая распаковка архивов (ADD) может быть рискованной, если архив содержит файлы с абсолютными путями (tarbomb).

Когда использовать ADD?

Единственный оправданный случай — когда вам нужно скопировать локальный tar-архив и сразу же его распаковать в один слой. В остальных случаях COPY является более безопасным и ясным выбором.