Вопрос: В чем разница между командами `COPY` и` ADD` в файле Docker?


В чем разница между COPYа также ADDкоманды в файле Docker, и когда я буду использовать один над другим?


COPY <src> <dest>

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


ADD <src> <dest>

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


1420


источник


Ответы:


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

  • ADDпозволяет <src>быть URL-адресом
  • Если <src>параметр ADDэто архив в распознанном формате сжатия, он будет распакован

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


1406



COPYявляется

То же, что и «ADD», но без обработки tar и удаленного URL.

Справка прямо из исходного кода ,


283



По этому поводу имеется официальная документация: Рекомендации по написанию докеров

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

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«Звездная автоматическая экстракция», вы всегда должны использовать COPY,


115



Из документов Docker:

ДОБАВИТЬ ИЛИ КОПИРОВАТЬ

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

Больше: Рекомендации по написанию Dockerfiles


94



If you want to add a xx.tar.gz to a /usr/local in container, unzip it, and then remove the useless compressed package.

For COPY:

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

For ADD:

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

ADD supports local-only tar extraction. Besides it, COPY will use three layers, but ADD only uses one layer.


25



From Docker docs: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

"Although ADD and COPY are functionally similar, generally speaking, COPY is preferred. That’s because it’s more transparent than ADD. COPY only supports the basic copying of local files into the container, while ADD has some features (like local-only tar extraction and remote URL support) that are not immediately obvious. Consequently, the best use for ADD is local tar file auto-extraction into the image, as in ADD rootfs.tar.xz /.

If you have multiple Dockerfile steps that use different files from your context, COPY them individually, rather than all at once. This will ensure that each step’s build cache is only invalidated (forcing the step to be re-run) if the specifically required files change.

For example:

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

Results in fewer cache invalidations for the RUN step, than if you put the COPY . /tmp/ before it.

Because image size matters, using ADD to fetch packages from remote URLs is strongly discouraged; you should use curl or wget instead. That way you can delete the files you no longer need after they’ve been extracted and you won’t have to add another layer in your image. For example, you should avoid doing things like:

 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

And instead, do something like:

 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

For other items (files, directories) that do not require ADD’s tar auto-extraction capability, you should always use COPY."


11



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

This is another way to copy files into an image. The -v option temporarily creates a volume that us used during the build process.

This is different that other volumes because it mounts a host directory for the build only. Files can be copied using a standard cp command.

Also, like the curl and wget, it can be run in a command stack (runs in a single container) and not multiply the image size. ADD and COPY are not stackable because they run in a standalone container and subsequent commands on those files that execute in additional containers will multiply the image size:

With the options set thus:

-v /opt/mysql-staging:/tvol

The following will execute in one container:

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

0



Important Note

I had to copy and untar java package in my docker image. When I compared the docker image size created using ADD it was 180MB bigger then the one created using COPY, tar -xzf *.tar.gz and rm *.tar.gz

This means that although ADD removes the tar file, it is still kept somewhere. And its making the image big!!


0



COPY copies a file/directory from your host to your image.

ADD copies a file/directory from your host to your image, but can also fetch remote URLs, extract TAR files, etc...

Use COPY for simply copying files and/or directories into the build context.

Use ADD for downloading remote resources, extracting TAR files, etc..


0