Quelle est la différence entre les commandes `COPY` et `ADD` dans un fichier Dockerfile?

Quelle est la différence entre les commandes COPY et ADD dans un Dockerfile, et quand devrais-je utiliser l'une sur l'autre?


COPY <src> <dest>

L'instruction COPY va copier les nouveaux fichiers de <src> et les ajouter à le système de fichiers du conteneur à path <dest>


ADD <src> <dest>

L'instruction ADD copiera les nouveaux fichiers de <src> et les ajoutera au système de fichiers du conteneur à path <dest>.

1564
demandé sur sk8forether 2014-07-25 18:31:20

10 réponses

, Vous devez vérifier la ADD et COPY la documentation pour une description exhaustive de leurs comportements, mais en un mot, la différence majeure est que les ADD peut faire plus de COPY:

  • ADD permet à <src> d'être une URL
  • si le paramètre <src> de ADD est une archive dans un format de compression reconnu, elle sera décompressée

Notez que les meilleures pratiques pour écrire des fichiers Dockerfiles suggère d'utiliser COPY où la magie de ADD n'est pas nécessaire. Sinon, vous (puisque vous avez dû rechercher cette réponse) risquez d'être surpris un jour lorsque vous voulez copier keep_this_archive_intact.tar.gz dans votre conteneur, mais que vous pulvérisez le contenu sur votre système de fichiers.

1568
répondu icecrime 2018-08-04 16:34:47

COPY est

Identique à 'ADD', mais sans le TAR et la gestion des URL distantes.

Référence directement à partir du code source .

310
répondu caike 2017-10-25 17:00:46

Il existe une documentation officielle sur ce point: meilleures pratiques pour écrire des fichiers Dockerfiles

Étant donné que la taille de l'image est importante, l'utilisation de ADD pour récupérer des paquets à partir D'URL distantes est fortement déconseillée; vous devez utiliser curl ou wget à la place. De cette façon, vous pouvez supprimer les fichiers dont vous n'avez plus besoin après qu'ils ont été extraits et vous n'aurez pas à ajouter un autre calque dans votre image.

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

Pour d'autres éléments (fichiers, répertoires) qui ne nécessitent pas La capacité d'auto-extraction tar de ADD, vous devez toujours utiliser COPY.

116
répondu Victor Laskin 2016-10-31 00:35:18

À partir des documents Docker:

Ajouter ou copier

Bien que ADD et COPY soient fonctionnellement similaires, D'une manière générale, COPY est préféré. C'est parce que C'est plus transparent que ADD. COPY ne prend en charge que la copie de base des fichiers locaux dans le conteneur, tandis que ADD possède certaines fonctionnalités (comme l'extraction de tar uniquement locale et le support des URL distantes) qui ne sont pas immédiatement évidentes. Par conséquent, la meilleure utilisation pour ADD est l'extraction automatique du fichier tar local dans L'image, comme dans ADD rootfs.tar.xz /.

Plus: meilleures pratiques pour écrire des fichiers Dockerfiles

95
répondu eddd 2016-10-31 00:35:53

Si vous voulez ajouter un xx.tar.gz à un /usr/local dans le conteneur, décompressez-le, puis supprimez le paquet compressé inutile.

Pour la copie:

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

Pour ajouter:

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

ADD prend en charge l'extraction de goudron uniquement locale. En outre, COPY utilisera trois couches, mais ADD n'utilise qu'une seule couche.

27
répondu BertLi 2017-03-15 18:40:35

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

" bien que ADD et COPY soient fonctionnellement similaires, D'une manière générale, COPY est préféré. C'est parce que C'est plus transparent que ADD. COPY ne prend en charge que la copie de base des fichiers locaux dans le conteneur, tandis que ADD possède certaines fonctionnalités (comme l'extraction de tar uniquement locale et le support des URL distantes) qui ne sont pas immédiatement évidentes. Par conséquent, la meilleure utilisation pour ADD est extraction automatique du fichier tar local dans l'image, comme dans ajouter des rootfs.tar.xz /.

Si vous avez plusieurs étapes Dockerfile qui utilisent des fichiers différents de votre contexte, copiez-les individuellement, plutôt que tous à la fois. Cela garantira que le cache de construction de chaque étape est seulement invalidé (forçant l'étape à être réexécutée) si les fichiers spécifiquement requis changent.

Par exemple:

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

Entraîne moins d'invalidations du cache pour L'étape D'exécution que si vous mettez la copie . /tmp/ avant il.

Étant donné que la taille de l'image est importante, l'utilisation de ADD to fetch packages from remote URLs est fortement déconseillée; vous devez utiliser curl ou wget à la place. De cette façon, vous pouvez supprimer les fichiers dont vous n'avez plus besoin après qu'ils ont été extraits et vous n'aurez pas à ajouter un autre calque dans votre image. Par exemple, vous devriez éviter de faire des choses comme:

 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

Et à la place, faites quelque chose comme:

 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

Pour les autres éléments (fichiers, répertoires) qui ne nécessitent pas la capacité D'extraction automatique tar D'ADD, vous devriez toujours utiliser COPY."

11
répondu jhpg 2016-08-24 14:33:41

COPY copie un fichier / répertoire de votre hôte vers votre image.

ADD copie un fichier / répertoire de votre hôte vers votre image, mais peut également récupérer des URL distantes,extraire des fichiers TAR, etc...

Utilisation COPY pour simplement copier des fichiers et / ou des répertoires dans le contexte de construction.

Utilisation ADD pour télécharger des ressources distantes, extraire des fichiers TAR, etc..

2
répondu JSON C11 2018-05-31 12:11:18

COPY et ADD sont les deux instructions Dockerfile qui servent des objectifs similaires. Ils vous permettent de copier des fichiers à partir d'un emplacement spécifique dans une image Docker.

COPY prend un src et une destination. Il vous permet uniquement de copier dans un fichier ou un répertoire local à partir de votre hôte (la machine qui construit L'image Docker) dans l'image Docker elle-même.

ADD vous permet de le faire aussi, mais il prend également en charge 2 autres sources. Tout d'abord, vous pouvez utiliser une URL au lieu d'un fichier / répertoire local. Deuxièmement, vous pouvez extraire un fichier tar de la source directement dans la destination

Un cas d'utilisation valide pour ADD est lorsque vous souhaitez extraire un fichier tar local dans un répertoire spécifique de votre image Docker.

Si vous copiez des fichiers locaux sur votre image Docker, utilisez toujours COPY car c'est plus explicite.

Référence: https://nickjanetakis.com/blog/docker-tip-2-the-difference-between-copy-and-add-in-a-dockerile

0
répondu Shagun Pruthi 2018-08-16 07:10:51

Remarque Importante

J'ai dû COPY et décompresser le paquet java dans mon image docker. Lorsque j'ai comparé la taille de l'image Docker créée en utilisant ADD, elle était 180MB plus grande que celle créée en utilisant COPY, tar-xzf *.tar.gz et rm*.tar.gz

Cela signifie que bien que ADD supprime le fichier tar, il est toujours conservé quelque part. Et sa prise de l'image en plus grand!!

0
répondu Avi Veltz 2018-09-28 07:23:39
docker build -t {image name} -v {host directory}:{temp build directory} .

C'est une autre façon de copier des fichiers dans une image. L'option-v crée temporairement un volume que nous avons utilisé pendant le processus de construction.

Ceci est différent des autres volumes car il monte un répertoire hôte pour la construction uniquement. Les fichiers peuvent être copiés à l'aide d'une commande cp standard.

En outre, comme le curl et wget, il peut être exécuté dans une pile de commandes (s'exécute dans un seul conteneur) et ne pas multiplier la taille de l'image. ADD et COPY ne sont pas empilables car ils s'exécutent dans un le conteneur autonome et les commandes suivantes sur les fichiers qui s'exécutent dans des conteneurs supplémentaires multiplieront la taille de l'image:

, Avec les options définies ainsi:

-v /opt/mysql-staging:/tvol

Ce qui suit s'exécutera dans un conteneur:

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
-1
répondu Dennis Payne 2016-09-23 21:25:28