it-swarm.com.de

Was ist der Unterschied zwischen den Befehlen "KOPIEREN" und "HINZUFÜGEN" in einer Docker-Datei?

Was ist der Unterschied zwischen den Befehlen COPY und ADD in einer Docker-Datei, und wann würde ich einen über den anderen verwenden?

COPY <src> <dest>

Die COPY-Anweisung kopiert neue Dateien aus <src> und fügt sie dem Dateisystem des Containers unter dem Pfad <dest> hinzu.

ADD <src> <dest>

Die ADD-Anweisung kopiert neue Dateien aus <src> und fügt sie dem Dateisystem des Containers unter dem Pfad <dest> hinzu.

1899
Steve

Sie sollten die Dokumentation zu ADD und COPY lesen, um eine ausführliche Beschreibung ihres Verhaltens zu erhalten. Der Hauptunterschied besteht jedoch darin, dass ADD kann mehr als COPY:

  • Mit ADD kann <src> eine URL sein
  • In den nachstehenden Kommentaren wird in der ADDDokumentation eindeutig Folgendes angegeben:

    Wenn es sich um ein lokales tar-Archiv in einem erkannten Komprimierungsformat (identity, gzip, bzip2 oder xz) handelt, wird es als Verzeichnis entpackt. Ressourcen von entfernten URLs werden nicht dekomprimiert.

Beachten Sie, dass in Best Practices für das Schreiben von Dock-Dateien die Verwendung von COPY empfohlen wird, wenn die Magie von ADD nicht erforderlich ist. Andernfalls werden Sie (da Sie diese Antwort nachschlagen mussten) wahrscheinlich eines Tages überrascht sein, wenn Sie keep_this_archive_intact.tar.gz In Ihren Container kopieren möchten, aber stattdessen sprühen Sie den Inhalt auf Ihr Dateisystem.

1905
icecrime

COPY ist

Entspricht 'ADD', jedoch ohne die Behandlung von tar und entfernten URLs.

Referenz direkt aus dem Quellcode .

398
caike

Zu diesem Punkt gibt es eine offizielle Dokumentation: Best Practices for Writing Dockerfiles

Da es auf die Bildgröße ankommt, wird dringend davon abgeraten, ADD zum Abrufen von Paketen von fernen URLs zu verwenden. Sie sollten stattdessen curl oder wget verwenden. Auf diese Weise können Sie die Dateien löschen, die Sie nach dem Extrahieren nicht mehr benötigen, und müssen Ihrem Bild keine weitere Ebene hinzufügen.

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

Für andere Elemente (Dateien, Verzeichnisse), für die die automatische Tar-Extraktionsfunktion von ADD nicht erforderlich ist, sollten Sie immer COPY verwenden.

129
Victor Laskin

In Docker-Dokumenten:

HINZUFÜGEN oder KOPIEREN

Obwohl ADD und COPY funktional ähnlich sind, wird COPY im Allgemeinen bevorzugt. Das liegt daran, dass es transparenter ist als ADD. COPY unterstützt nur das grundlegende Kopieren lokaler Dateien in den Container, während ADD einige Funktionen (wie die reine lokale Teer-Extraktion und die Unterstützung von Remote-URLs) bietet, die nicht sofort ersichtlich sind. Folglich ist die beste Verwendung für ADD die automatische Extraktion lokaler TAR-Dateien in das Image, wie in ADD rootfs.tar.xz /.

Mehr: Best Practices zum Schreiben von Dockerfiles

108
eddd

Wenn Sie einem /usr/local -In-Container ein xx.tar.gz hinzufügen möchten, entpacken Sie es und entfernen Sie das unbrauchbare komprimierte Paket.

Für KOPIEREN:

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

Für ADD:

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

ADD unterstützt nur die lokale Teergewinnung. Außerdem verwendet COPY drei Ebenen, während ADD nur eine Ebene verwendet.

37
BertLi

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

"Obwohl ADD und COPY funktional im Allgemeinen ähnlich sind, wird COPY bevorzugt. Dies liegt daran, dass es transparenter als ADD ist. COPY unterstützt nur das grundlegende Kopieren lokaler Dateien in den Container, während ADD einige Funktionen aufweist (z (Unterstützung für Remote-URLs), die nicht sofort ersichtlich sind. Folglich ist die automatische Extraktion von lokalen TAR-Dateien in das Image die beste Verwendung für ADD, wie in ADD rootfs.tar.xz /.

Wenn Sie über mehrere Dockerfile-Schritte verfügen, die unterschiedliche Dateien aus Ihrem Kontext verwenden, KOPIEREN Sie diese einzeln und nicht alle auf einmal. Auf diese Weise wird sichergestellt, dass der Build-Cache jedes Schritts nur ungültig wird (wodurch ein erneuter Start des Schritts erzwungen wird), wenn sich die speziell erforderlichen Dateien ändern.

Zum Beispiel:

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

Führt zu weniger Cache-Invalidierungen für den RUN-Schritt als beim Kopieren./tmp/davor.

Da es auf die Bildgröße ankommt, wird dringend davon abgeraten, ADD zum Abrufen von Paketen von Remote-URLs zu verwenden. Sie sollten stattdessen Curl oder Wget verwenden. Auf diese Weise können Sie die Dateien löschen, die Sie nach dem Extrahieren nicht mehr benötigen, und müssen Ihrem Bild keine weitere Ebene hinzufügen. Sie sollten beispielsweise Folgendes vermeiden:

 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

Und machen Sie stattdessen etwas wie:

 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

Für andere Elemente (Dateien, Verzeichnisse), für die keine automatische Tar-Extraktionsfunktion von ADD erforderlich ist, sollten Sie immer COPY verwenden. "

13
jhpg

COPY kopiert eine Datei/ein Verzeichnis von Ihrem Host auf Ihr Image.

ADD kopiert eine Datei/ein Verzeichnis von Ihrem Host auf Ihr Image, kann aber auch entfernte URLs abrufen, TAR-Dateien extrahieren usw.

Verwenden Sie COPY, um einfach Dateien und/oder Verzeichnisse in den Build-Kontext zu kopieren.

Verwenden Sie ADD, um Remote-Ressourcen herunterzuladen, TAR-Dateien zu extrahieren usw.

9
JSON C11

COPY

Dadurch werden eine oder mehrere lokale Dateien oder Ordner in das Ziel in Ihrem Docker-Image kopiert.

COPY < src> < dest >

COPY ["< source >",... "< destination >"] 

(Dieses Formular ist für Pfade mit Leerzeichen erforderlich.)

Ein Beispiel für eine Docker-Datei, die COPY verwendet So würden Sie COPY in einer Docker-Datei für eine Ruby App verwenden.

FROM Ruby:2.5.1
WORKDIR /usr/src/app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
CMD ["./your-daemon-or-script.rb"]

Es baut das Bild in Ebenen auf, beginnend mit dem übergeordneten Bild Ruby: 2.5.1, das mit FROM definiert wurde.

Die Docker-Anweisung WORKDIR definiert ein Arbeitsverzeichnis für die darauf folgenden Anweisungen COPY oder ADD.

Durch Kopieren von Gemfiles gefolgt von RUN bundle install wird eine Bildebene mit den installierten Ruby Gems erstellt, die zwischengespeichert werden können. In den letzten beiden Docker-Anweisungen werden die Dateien der App in das Image kopiert und der Standardbefehl mit CMD festgelegt.

Wenn Sie also eine der App-Dateien ändern, können Sie das Docker-Image mithilfe der zwischengespeicherten übergeordneten Ebene und der Zwischenebene neu erstellen. Dies ist viel effizienter als alle von Grund auf neu zu erstellen.

_ _ hinzufügen

Diese Anweisung hat eine ähnliche Syntax wie COPY.

ADD < src> < dest >

ADD ["< source >",... "< destination >"] (this form is required for paths containing whitespace)

Es kopiert nicht nur lokale Dateien und Verzeichnisse in das Ziel im Docker-Image, sondern bietet auch einige zusätzliche Funktionen:

Wenn <source> ein lokales Tar-Archiv in einem erkannten Komprimierungsformat ist, wird es automatisch als Verzeichnis in das Docker-Image entpackt. Zum Beispiel: ADD rootfs.tar.xz /

Wenn der <source> eine URL ist, wird die Datei heruntergeladen und in das Ziel im Docker-Image kopiert. Docker rät jedoch davon ab, ADD für diesen Zweck zu verwenden.

Best Practice Dockerfile zum Kopieren von einer URL

Docker schlägt vor, dass das Kopieren von einer URL mithilfe von ADD häufig nicht effizient ist, und es wird empfohlen, andere Strategien zu verwenden, um die erforderlichen Remotedateien einzuschließen.

Da es auf die Bildgröße ankommt, wird dringend davon abgeraten, ADD zum Abrufen von Paketen von Remote-URLs zu verwenden. Sie sollten stattdessen Curl oder Wget verwenden. Auf diese Weise können Sie die Dateien löschen, die Sie nach dem Extrahieren nicht mehr benötigen, und müssen Ihrem Bild keine weitere Ebene hinzufügen. - Bewährte Dockerfile-Methoden

Sie sollten beispielsweise Folgendes vermeiden:

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

Und machen Sie stattdessen etwas wie:

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

Für andere Elemente (Dateien, Verzeichnisse), für die die automatische Tar-Extraktionsfunktion von ADD nicht erforderlich ist, sollten Sie immer COPY verwenden.

5
Prakash

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

COPY und ADD sind Dockerfile-Anweisungen, die ähnlichen Zwecken dienen. Sie können Dateien von einem bestimmten Speicherort in ein Docker-Image kopieren.

COPY nimmt eine Quelle und ein Ziel auf. Sie können nur eine lokale Datei oder ein lokales Verzeichnis von Ihrem Host (dem Computer, auf dem das Docker-Image erstellt wurde) in das Docker-Image selbst kopieren.

Mit ADD können Sie dies auch tun, es werden jedoch auch 2 andere Quellen unterstützt. Erstens können Sie eine URL anstelle einer lokalen Datei/eines lokalen Verzeichnisses verwenden. Zweitens können Sie eine TAR-Datei von der Quelle direkt in das Ziel extrahieren

Ein gültiger Anwendungsfall für ADD ist, wenn Sie eine lokale tar-Datei in ein bestimmtes Verzeichnis in Ihrem Docker-Image extrahieren möchten.

Wenn Sie lokale Dateien in Ihr Docker-Image kopieren, verwenden Sie immer COPY, da dies expliziter ist.

4
Shagun Pruthi

Wichtige Notiz

Ich musste in meinem Docker-Image COPY und Java entpacken. Wenn ich die mit ADD erstellte Docker-Bildgröße verglich, war sie 180 MB größer als die mit COPY erstellte, tar -xzf * .tar.gz und rm * .tar.gz

Dies bedeutet, dass ADD die TAR-Datei zwar entfernt, sie jedoch an einem beliebigen Ort aufbewahrt wird. Und es macht das Bild größer !!

2
Avi Veltz

Seit Docker 17.05 wird COPY mit dem Flag --from in mehrstufigen Builds verwendet, um Artefakte aus vorherigen Build-Phasen in die aktuelle Build-Phase zu kopieren.

aus der Dokumentation

Optional akzeptiert COPY ein Flag --from=<name|index>, mit dem der Quellspeicherort auf eine vorherige Erstellungsstufe (erstellt mit FROM .. AS) festgelegt werden kann, die anstelle eines vom Benutzer gesendeten Erstellungskontexts verwendet wird.

0
MCI
docker build -t {image name} -v {Host directory}:{temp build directory} .

Dies ist eine weitere Möglichkeit, Dateien in ein Bild zu kopieren. Die Option -v erstellt vorübergehend ein Volume, das wir während des Erstellungsprozesses verwendet haben.

Dies unterscheidet sich von anderen Volumes, da ein Hostverzeichnis nur für den Build bereitgestellt wird. Dateien können mit einem Standard-Befehl cp kopiert werden.

Ebenso wie curl und wget kann es in einem Befehlsstapel ausgeführt werden (wird in einem einzelnen Container ausgeführt), ohne die Bildgröße zu multiplizieren. ADD und COPY können nicht gestapelt werden, da sie in einem eigenständigen Container ausgeführt werden und nachfolgende Befehle für die Dateien, die in zusätzlichen Containern ausgeführt werden, die Bildgröße multiplizieren:

Mit den so eingestellten Optionen:

-v /opt/mysql-staging:/tvol

Folgendes wird in einem Container ausgeführt:

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
Dennis Payne