← Назад к вопросам
В чем разница между COPY и ADD в Docker?
1.3 Junior🔥 141 комментариев
#DevOps и инфраструктура
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# COPY vs ADD в Docker
Это часто задаваемый вопрос для Docker разработчиков. На первый взгляд кажется, что COPY и ADD одинаковые, но есть важные различия.
Быстрое сравнение
| Команда | Копирует файлы | Распаковывает архивы | Берёт из URL | Сложность |
|---|---|---|---|---|
| COPY | ✅ Да | ❌ Нет | ❌ Нет | Простая |
| ADD | ✅ Да | ✅ Да | ✅ Да | Сложная |
Правило: Используй COPY по умолчанию. ADD только если нужна специальная функциональность.
1. COPY — простое копирование
Основное назначение
СКОПИРОВАТЬ файлы и папки с хоста в контейнер.
FROM python:3.11
# Копируем requirements
COPY requirements.txt /app/
# Копируем исходный код
COPY src/ /app/src/
# Копируем конфиг
COPY config.yaml /app/config.yaml
WORKDIR /app
RUN pip install -r requirements.txt
Синтаксис
# Копировать файл
COPY source.txt /app/source.txt
# Копировать директорию
COPY ./src/ /app/src/
# Копировать несколько файлов
COPY file1.txt file2.txt file3.txt /app/
# Копировать с переименованием
COPY ./config.yaml /app/settings.yaml
# Wildcards
COPY *.txt /app/ # Копирует все .txt файлы
COPY ./src/**/*.py /app/src/ # Копирует рекурсивно
Внутри контейнера
FROM ubuntu:22.04
COPY myfile.txt /data/myfile.txt
COPY mydir/ /data/mydir/
# Результат в контейнере:
# /data/myfile.txt
# /data/mydir/file1.txt
# /data/mydir/file2.txt
2. ADD — копирование + особенности
Синтаксис идентичен COPY
FROM python:3.11
ADD requirements.txt /app/
ADD src/ /app/src/
ADD config.yaml /app/config.yaml
Но ADD имеет ДОПОЛНИТЕЛЬНЫЕ возможности:
Функция 1: Автоматическая распаковка архивов
FROM ubuntu:22.04
# Копируем tar.gz файл
ADD myapp.tar.gz /app/
# Результат:
# /app/ (распакован архив)
# /app/file1.txt
# /app/file2.txt
# /app/subdir/
# Поддерживаемые форматы:
# - .tar
# - .tar.gz
# - .tar.bz2
# - .tar.xz
# - .zip
Практический пример
# Загружаем архив с исходным кодом
ADD source-code-1.0.tar.gz /app/
WORKDIR /app
RUN ./build.sh
# Эквивалент с COPY требует дополнительных команд
COPY source-code-1.0.tar.gz /app/
WORKDIR /app
RUN tar -xzf source-code-1.0.tar.gz && rm source-code-1.0.tar.gz
RUN ./build.sh
Функция 2: Копирование из URL
FROM ubuntu:22.04
# ADD может скачать файл из интернета!
ADD https://example.com/data.tar.gz /app/data.tar.gz
# Если это архив - распакует автоматически
ADD https://example.com/code.tar.gz /app/code/
# Результат: /app/code/ (распакован)
COPY vs ADD: Подробное сравнение
Case 1: Простое копирование файлов
# ✅ COPY - правильный выбор
COPY requirements.txt /app/requirements.txt
# ⚠️ ADD - тоже работает, но неправильный выбор
ADD requirements.txt /app/requirements.txt
Оба работают одинаково. COPY предпочтительнее за прозрачность.
Case 2: Распаковка архива
# ❌ COPY не может распаковать
COPY myapp.tar.gz /app/
RUN cd /app && tar -xzf myapp.tar.gz && rm myapp.tar.gz
# ✅ ADD распакует автоматически
ADD myapp.tar.gz /app/
# Файлы уже распакованы в /app/
Но есть проблема:
# ADD распакует архив в целевую директорию
ADD app.tar.gz /app/
# Если архив содержит 'app/', результат:
# /app/app/files...
# Часто нужна дополнительная обработка
# Лучше быть явным
COPY app.tar.gz /tmp/
RUN cd /tmp && tar -xzf app.tar.gz && mv app/* /app/
Case 3: Скачивание из интернета
# ✅ ADD может скачать
ADD https://example.com/data.tar.gz /data/
# ❌ COPY не может
COPY https://example.com/data.tar.gz /data/ # ОШИБКА!
# Эквивалент с COPY + RUN
RUN curl -O https://example.com/data.tar.gz \
&& tar -xzf data.tar.gz -C /data \
&& rm data.tar.gz
Проблемы с ADD
1. Неожиданное поведение
ADD archive.tar.gz /app/
# Пользователь может ожидать:
# /app/archive.tar.gz (просто файл)
# На самом деле:
# /app/ (архив распакован!)
# /app/content/ (содержимое архива)
2. Layer caching
# COPY - кеш работает хорошо
COPY requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt
COPY src/ /app/src/ # Если requirements не изменился,
# слой переиспользуется
# ADD с URL - кеш может быть неправильным
ADD https://api.example.com/data.json /data.json
# Docker не знает, изменился ли файл на сервере
# Кеш может быть устаревшим
3. Безопасность
# Опасно - скачиваем файл из интернета без контроля
ADD https://example.com/unknown-file.tar.gz /app/
# Безопаснее - явно скачиваем и проверяем
RUN curl -O https://example.com/file.tar.gz \
&& echo 'abc123' | sha256sum -c - file.tar.gz \
&& tar -xzf file.tar.gz
Best Practices
✅ Используй COPY
FROM python:3.11-slim
# Копируем requirements
COPY requirements.txt /app/
# Копируем исходный код
COPY src/ /app/src/
# Копируем конфиги
COPY config/ /app/config/
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["python", "main.py"]
⚠️ Используй ADD только если нужна специальная функциональность
FROM ubuntu:22.04
# Нужна автоматическая распаковка архива
ADD app-v1.0.tar.gz /opt/
# Остальное - COPY
COPY startup.sh /opt/startup.sh
COPY config.yaml /opt/config.yaml
ENTRYPOINT ["/opt/startup.sh"]
✅ Лучше быть явным
# Вместо автоматической распаковки через ADD
ADD code.tar.gz /app/
# Лучше явно распаковать
COPY code.tar.gz /tmp/
RUN tar -xzf /tmp/code.tar.gz -C /app && rm /tmp/code.tar.gz
# Почему?
# 1. Понятнее что происходит
# 2. Контроль над результатом
# 3. Можно проверить контрольные суммы
# 4. Проще отладить
✅ Скачивание файлов
# ❌ Неправильно
ADD https://example.com/large-file.tar.gz /data/
# ✅ Правильно
RUN curl -fsSL https://example.com/large-file.tar.gz \
-o /tmp/file.tar.gz && \
tar -xzf /tmp/file.tar.gz -C /data && \
rm /tmp/file.tar.gz
# ✅ Ещё лучше с проверкой контрольной суммы
RUN curl -fsSL https://example.com/large-file.tar.gz \
-o /tmp/file.tar.gz && \
echo "abc123def456..." | sha256sum -c - /tmp/file.tar.gz && \
tar -xzf /tmp/file.tar.gz -C /data && \
rm /tmp/file.tar.gz
Резюме для собеседования
Основное различие
COPY:
- Копирует файлы и папки
- Простая и понятная
- Рекомендуется в 99% случаев
- Хороший layer caching
ADD:
- Копирует файлы и папки (как COPY)
-
- Распаковывает архивы (tar, zip, etc)
-
- Может скачивать из URL
- Менее понятна, может дать неожиданный результат
- Использовать только если нужна дополнительная функциональность
Лучшая практика
FROM python:3.11-slim
# Используй COPY для файлов
COPY requirements.txt /app/
COPY src/ /app/src/
# Используй RUN + curl для скачиваний
RUN curl -fsSL https://example.com/data.tar.gz | tar -xz -C /data
# Добавляй ADD только если архив уже в контексте build'а
ADD local-archive.tar.gz /app/ # Может быть оправдано
WORKDIR /app
RUN pip install -r requirements.txt
Это важное знание для оптимизации Docker образов и написания чистых Dockerfile'ов.