В чем разница между командами "копировать" и "добавить" в Dockerfile?

в чем разница между COPY и ADD команды в Dockerfile и когда я должен использовать один над другим?


COPY <src> <dest>

инструкция копирования будет копировать новые файлы из <src> и добавить их в файловая система контейнера в пути <dest>


ADD <src> <dest>

инструкция ADD будет копировать новые файлы из <src> и добавить их в файловая система контейнера в пути <dest>.

10 ответов


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

  • ADD позволяет <src> быть URL
  • если

COPY is

то же, что и "добавить", но без обработки tar и удаленного URL.

ссылка прямо из исходного кода.


существует некоторая официальная документация по этому вопросу:лучшие практики для написания Dockerfiles

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

RUN mkdir -p /usr/src/things \
  && curl -SL http://example.com/big.tar.gz \
    | tar -xJC /usr/src/things \
  && make -C /usr/src/things all

для других элементов (файлы, каталоги), которые не требуют ADD возможность автоматического извлечения tar, вы всегда должны использовать COPY.


из Docker docs:

добавить или скопировать

хотя ADD и COPY функционально похожи, вообще говоря, COPY предпочтительнее. Это потому, что это более прозрачно, чем ADD. Копирование поддерживает только базовое копирование локальных файлов в контейнер, в то время как ADD имеет некоторые функции (например, локальное извлечение tar и удаленная поддержка URL), которые не сразу очевидны. Следовательно, наилучшим использованием для ADD является автоматическое извлечение локального файла tar в изображение, как в ADD rootfs.смола.ХZ /.

Подробнее: лучшие практики для написания Dockerfiles


Если вы хотите добавить xx.деготь.gz to a /usr/local в контейнере распакуйте его, а затем удалите бесполезный сжатый пакет.

для копирования:

COPY resources/jdk-7u79-linux-x64.tar.gz /tmp/
RUN tar -zxvf /tmp/jdk-7u79-linux-x64.tar.gz -C /usr/local
RUN rm /tmp/jdk-7u79-linux-x64.tar.gz

АДД:

ADD resources/jdk-7u79-linux-x64.tar.gz /usr/local/

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


из документов Docker: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

" хотя ADD и COPY функционально похожи, вообще говоря, предпочтительнее копировать. Это потому, что это более прозрачно, чем ADD. Копирование поддерживает только базовое копирование локальных файлов в контейнер, в то время как ADD имеет некоторые функции (например, локальное извлечение tar и удаленная поддержка URL), которые не сразу очевидны. Следовательно, самое лучшее для добавления используется локальное автоматическое извлечение файла tar в изображение, как в ADD rootfs.смола.ХZ /.

Если у вас есть несколько шагов Dockerfile, которые используют разные файлы из вашего контекста, скопируйте их по отдельности, а не все сразу. Это гарантирует, что кэш сборки каждого шага будет недействительным (принудительное повторное выполнение шага) только при изменении специально необходимых файлов.

например:

 COPY requirements.txt /tmp/
 RUN pip install --requirement /tmp/requirements.txt
 COPY . /tmp/

приводит к меньшему количеству недействительности кэша для шага выполнения, чем если ты положил копию . / tmp / перед ним.

поскольку размер изображения имеет значение, использование ADD для извлечения пакетов из удаленных URL-адресов настоятельно не рекомендуется; вместо этого следует использовать curl или wget. Таким образом, вы можете удалить файлы, которые вам больше не нужны после их извлечения, и вам не придется добавлять другой слой в изображение. Например, вы должны избегать делать такие вещи, как:

 ADD http://example.com/big.tar.xz /usr/src/things/
 RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
 RUN make -C /usr/src/things all

и вместо этого сделать что-то вроде:

 RUN mkdir -p /usr/src/things \
     && curl -SL htt,p://example.com/big.tar.xz \
     | tar -xJC /usr/src/things \
     && make -C /usr/src/things all

для других элементов (файлов, каталогов) это не требует возможности автоматического извлечения tar ADD, вы всегда должны использовать COPY."


COPY копирует файл/каталог с вашего хоста в ваш образ.

ADD копирует файл / каталог с вашего хоста на изображение, но также может извлекать удаленные URL-адреса, извлекать файлы TAR и т. д...

использовать COPY для простого копирования файлов и/или каталогов в контексте сборки.

использовать ADD для загрузки удаленных ресурсов, извлечения файлов TAR и т. д..


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

COPY принимает src и назначение. Он позволяет копировать только локальный файл или каталог с хоста (машина, создающая образ Docker) в сам образ Docker.

ADD позволяет сделать это тоже, но он также поддерживает 2 других источника. Во-первых, вы можете использовать URL вместо локального файла / каталога. Во вторых, вы можете извлечь файл tar из источника непосредственно в пункт назначения

допустимым вариантом использования ADD является извлечение локального tar-файла в определенный каталог образа Docker.

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

ссылка : https://nickjanetakis.com/blog/docker-tip-2-the-difference-between-copy-and-add-in-a-dockerile


Важное Замечание

Я должен COPY и untar java-пакет в моем образе docker. Когда я сравнивал размер изображения docker, созданный с помощью ADD, он был на 180MB больше, чем тот, который был создан с помощью COPY, tar-xzf *.смола.gz и rm *.смола.gz

это означает, что, хотя ADD удаляет файл tar, он все еще хранится где-то. И это делает изображение больше!!


docker build -t {image name} -v {host directory}:{temp build directory} .

это еще один способ копирования файлов в изображение. Параметр-v временно создает том, который мы использовали в процессе сборки.

это отличается от других томов, потому что он монтирует каталог хоста только для сборки. Файлы могут быть скопированы с помощью стандартной команды cp.

кроме того, как curl и wget, он может быть запущен в стеке команд (работает в одном контейнере) и не умножать размер изображения. ADD и COPY не stackable потому что они запускаются в отдельном контейнере, и последующие команды на тех файлах, которые выполняются в дополнительных контейнерах, будут умножать размер изображения:

с параметрами, установленными таким образом:

-v /opt/mysql-staging:/tvol

в одном контейнере будет выполняться следующее:

RUN cp -r /tvol/mysql-5.7.15-linux-glibc2.5-x86_64 /u1 && \
    mv /u1/mysql-5.7.15-linux-glibc2.5-x86_64 /u1/mysql && \

    mkdir /u1/mysql/mysql-files && \
    mkdir /u1/mysql/innodb && \
    mkdir /u1/mysql/innodb/libdata && \
    mkdir /u1/mysql/innodb/innologs && \
    mkdir /u1/mysql/tmp && \

    chmod 750 /u1/mysql/mysql-files && \
    chown -R mysql /u1/mysql && \
    chgrp -R mysql /u1/mysql