Чем отличаются инструкции COPY и ADD в Dockerfile

Ответ

COPY и ADD — это инструкции в Dockerfile для копирования файлов в образ, но у них есть ключевые различия в функциональности и назначении.

COPY

Инструкция COPY имеет одну простую задачу: рекурсивно скопировать файлы и директории из исходного пути <src> в файловую систему контейнера по пути <dest>.

# Копирование одного файла
COPY ./requirements.txt /app/requirements.txt

# Копирование всей директории
COPY ./src /app/src

ADD

Инструкция ADD делает то же, что и COPY, но обладает двумя дополнительными возможностями:

  1. Распаковка архивов: Если исходный файл <src> является локальным архивом в формате tar, gzip, bzip2 или xz, он будет автоматически распакован в директорию назначения.
  2. Загрузка по URL: Если <src> является URL, файл будет загружен по этому адресу и скопирован в <dest>.
# Загрузка и сохранение файла
ADD https://example.com/file.txt /app/

# Автоматическая распаковка архива в /usr/local
ADD myapp.tar.gz /usr/local/

Ключевое правило и Best Practice

Всегда отдавайте предпочтение COPY. Его поведение прозрачно и предсказуемо — он только копирует файлы.

Используйте ADD только в тех редких случаях, когда вам действительно нужна его дополнительная функциональность (автоматическая распаковка tar-архивов). Для загрузки файлов по URL рекомендуется использовать связку RUN wget или RUN curl, так как это более гибкий и явный подход, позволяющий управлять процессом загрузки (например, удалять кэш после установки).

Ответ 18+ 🔞

А, слушай, вот эта тема про COPY и ADD в Dockerfile — это классика, блядь, вечный спор, как «Муму» топить или нет. Но тут всё проще, на самом деле.

Представь, у тебя есть два инструмента: обычный шуруповёрт и шуруповёрт с наворотами, который ещё и кофе может молоть, если насадку правильную прикрутить. Так вот COPY — это простой, надёжный шуруповёрт, а ADD — это этот самый мультитул с кофемолкой.

COPY — тупо копирует, и всё на этом.

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

# Берём файлик и кладём куда сказано
COPY ./requirements.txt /app/requirements.txt

# Берём целую папку и переносим
COPY ./src /app/src

ADD — делает то же самое, но, сука, с двумя приколами:

  1. Распаковка архивов. Подсунул ему myapp.tar.gz — а он его, блядь, сам развернул, как ковёр на полу. tar, gzip, bzip2, xz — он их жрёт и распаковывает автоматом.
  2. Скачивание по ссылке. Написал URL — он пошёл, скачал с интернетиков и закинул внутрь. Прямо как курьер, только бесплатный.
# Скачал файл с какого-то левого сайта и бросил в /app/
ADD https://example.com/file.txt /app/

# Принёс архив, а он его уже развёрнутый положил
ADD myapp.tar.gz /usr/local/

Главное правило, которое надо выжечь в мозгу

В 99% случаев бери COPY и не еби себе голову. Он предсказуемый, как удар тапком по лбу. Никаких внезапных распаковок там, где не ждал.

ADD используй только тогда, когда тебе реально, осознанно нужна его фишка с распаковкой архивов. А эту его способность скачивать по URL — забей, блядь. Это пиздопроебищно. Лучше явно напиши в Dockerfile:

RUN wget -O /app/file.txt https://example.com/file.txt && rm -rf /var/cache/apt/*

Так и понятнее, и мусор после себя прибрать можно. А ADD тебе так просто ссылку в кеш засорит, и потом будешь гадать, откуда лишние гигабайты.

Короче, запомни: COPY — твой рабочий мужик. ADD — это такой хитрожопый артист с сюрпризами. Нужны сюрпризы — ок. Не нужны — не трогай эту манду с ушами.