Ответ
Обе инструкции копируют файлы и директории из контекста сборки (хоста) в образ контейнера, но ADD обладает дополнительной функциональностью, которая часто не нужна и может привести к неожиданностям.
COPY <src> <dest>
- Назначение: Прямое и простое копирование локальных файлов/директорий.
- Поведение: Копирует файлы «как есть». Это предпочтительный и более предсказуемый выбор в большинстве случаев.
# Копирование одного файла
COPY package.json /app/
# Копирование всей директории
COPY ./src /app/src
ADD <src> <dest>
- Назначение: Копирование с дополнительными возможностями.
- Поведение:
- Автоматическая распаковка локальных архивов (
.tar,.tar.gz,.tar.bz2,.tar.xz,.gz) в месте назначения. - Поддержка URL-адресов в качестве источника
<src>. Файл скачивается из сети и копируется в образ.
- Автоматическая распаковка локальных архивов (
# Распаковка локального архива в директорию /app
ADD application.tar.gz /app/
# Скачивание файла из сети
ADD https://example.com/file.txt /tmp/
Практические рекомендации:
- Всегда используйте
COPY, если вам не нужны специфические возможностиADD. Это делает Dockerfile более понятным и предсказуемым. - Избегайте
ADDдля загрузки удаленных файлов. Скачивание лучше выполнять явно с помощьюRUNсcurlилиwget, так как это дает больше контроля (например, проверка контрольных сумм, обработка ошибок). Кэширование слоя сADDиз URL также работает иначе. - Распаковка архивов через
ADDможет быть неочевидной. Например, в архив могут входить скрытые файлы (вроде.git/), которые вы, возможно, не хотите копировать. Явная распаковка с помощьюRUN tar -xzfчасто безопаснее.