Ответ
Обе инструкции копируют файлы и директории из контекста сборки (хоста) в образ контейнера, но 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часто безопаснее.
Ответ 18+ 🔞
Давай разберём эту историю с COPY и ADD, а то тут, бля, такой овердохуища тонкостей, что сам от себя охуеешь. Вроде оба копируют, а разница — как между «просто занести пиво» и «занести пиво с внезапным стриптизом». Не всегда же нужен стриптиз, правда?
COPY <src> <dest> — это наш работяга, прямолинейный чувак.
Его задача проще некуда: взял файлы с хоста и положил в образ. Никаких фокусов, всё честно. Предсказуем, как восход солнца после хорошей пьянки. Его и надо юзать в 95% случаев.
# Кинул package.json куда надо — и всё
COPY package.json /app/
# Перекинул всю папку src — тоже без сюрпризов
COPY ./src /app/src
ADD <src> <dest> — это уже хитрая жопа с талантами.
Он тоже копирует, но если видит архив (типа .tar.gz), то сам его, бля, распаковывает. Ещё он может файлы прямо из интернета скачать, если ему ссылку дать.
# Сам распакует архив в /app. Удобно? Бывает.
ADD application.tar.gz /app/
# Полезет в интернет и скачает файл. Вообще доверия ебать ноль к такому.
ADD https://example.com/file.txt /tmp/
Так когда что использовать?
- Бери
COPYвсегда, если не уверен. Серьёзно, это как золотое правило. Хочешь предсказуемости —COPY. Волнение ебать не нужно, когда образ собираешь. ADDдля скачивания из сети — это пиздопроебибна идея. Лучше сделайRUN curl -o ...илиRUN wget. Хотя бы контроль над процессом будет, а тоADDтебе скачает, а ты и не поймёшь, что там внутри, если ссылка кривая.- Распаковка архивов через
ADD— тоже палка о двух концах. Он может тебе в образ незаметно натянуть какую-нибудь скрытую папку.gitили ещё какую дичь из архива. Явно распаковать черезRUN tar— надёжнее, хоть и дольше писать.
Короче, COPY — твой верный друг, а ADD — тот самый товарищ, с которым весело, но на которого лучше не полагаться в серьёзных делах.