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

«В чем разница между инструкциями COPY и ADD в Dockerfile?» — вопрос из категории Docker, который задают на 33% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

COPY <src>... <dest>

  • Копирует локальные файлы/директории из <src> (относительно контекста сборки) в <dest> внутри образа.
  • Рекомендуется использовать по умолчанию для простого копирования, так как его поведение предсказуемо и прозрачно.
    COPY ./package.json ./app.py /usr/src/app/
    COPY ./configs/ /etc/app/

ADD <src>... <dest>

  • Делает всё то же, что и COPY, плюс две специфические функции:
    1. Автоматическая распаковка локальных tar-архивов (.tar, .tar.gz, .tar.bz2 и т.д.) в пункте назначения.
      ADD ./application.tar.gz /opt/  # Содержимое архива будет распаковано в /opt/
    2. Поддержка URL в качестве <src>. Docker скачает файл по ссылке и поместит его в образ.
      ADD https://example.com/downloads/tool.tar.gz /tmp/

Практическое правило: Используйте COPY для простого копирования файлов вашего приложения. ADD стоит применять только тогда, когда вам действительно нужна его уникальная функциональность — например, для распаковки локального архива зависимостей. Избегайте ADD для скачивания файлов из сети, так как это делает образ зависимым от внешнего ресурса и усложняет кэширование; лучше выполнить скачивание явно с помощью RUN curl или RUN wget.