Moby: KOPIEREN mit ausgeschlossenen Dateien ist nicht möglich

Erstellt am 22. Aug. 2015  ·  82Kommentare  ·  Quelle: moby/moby

Ich muss einen _Teil_ eines Kontextverzeichnisses in den Container KOPIEREN (der andere Teil unterliegt einer anderen KOPIE). Leider sind die derzeitigen Möglichkeiten dafür suboptimal:

  1. KOPIEREN und beschneiden. Ich konnte das unerwünschte Material nach einem unbegrenzten KOPIEREN entfernen. Das Problem ist, dass sich das unerwünschte Material möglicherweise geändert hat, sodass der Cache ungültig wird.
  2. COPY jede Datei in einem eigenen COPY-Befehl. Dadurch werden dem Bild _viele_ unnötige Ebenen hinzugefügt.
  3. Einen Wrapper um den „docker build“-Aufruf schreiben, der den Kontext in irgendeiner Weise vorbereitet, damit das Dockerfile das gewünschte Material bequem kopieren kann. Umständlich und schwer zu pflegen.
arebuilder kinenhancement kinfeature

Hilfreichster Kommentar

+1 für dieses Problem, ich denke, es könnte auf die gleiche Weise unterstützt werden, wie es viele Glob-Bibliotheken unterstützen:

Hier ist ein Vorschlag, alles außer node_modules zu kopieren

COPY . /app -node_modules/

Alle 82 Kommentare

Siehe https://docs.docker.com/reference/builder/#dockerignore-file
Sie können Einträge zu einer .dockerignore-Datei im Stammverzeichnis des Projekts hinzufügen.

.dockerignore löst dieses Problem nicht. Wie ich schrieb, "der andere Teil unterliegt einer anderen KOPIE".

Sie möchten also auf der Grundlage einer anderen Kopie bedingt kopieren?

Der Kontext enthält viele Verzeichnisse A1...A10 und ein Verzeichnis B. A1...A10 haben ein Ziel, B hat ein anderes:

COPY A1 /some/where/A1/
COPY A2 /some/where/A2/
...
COPY A10 /some/where/A10/
COPY B some/where/else/B/

Und das ist umständlich.

Welcher Teil davon ist umständlich? Alle einzeln auflisten?

COPY A* /some/where/
COPY B /some/where/else/

Funktioniert das?

Die Namen A1..A10, B waren gefälscht. Außerdem wirft COPY A* ... die _Inhalte_ der Verzeichnisse zusammen.

Ich gebe zu, es gibt ein paar Optionen, aber ich denke, dass alle umständlich sind. Ich erwähnte drei in meinem ursprünglichen Posting. Eine vierte Möglichkeit besteht darin, meinen Quellcode dauerhaft neu zu ordnen, sodass A1..A10 in ein neues Verzeichnis A verschoben werden. Ich hatte gehofft, dass dies nicht erforderlich ist, da eine zusätzliche Verschachtelungsebene nicht erwünscht ist und meine aktuellen Tools dies erfordern Sonderfall dann meine dockerisierten Projekte.

(Übrigens, #6094 (folgende Symlinks) würde in diesem Fall helfen. Aber anscheinend ist dies auch keine Option.)

@bronger Wenn sich COPY genau wie cp #$ verhalten würde, würde das Ihren Anwendungsfall lösen?

Ich bin mir nicht sicher, ob ich es zu 100 % verstehe.
Vielleicht kann @duglin mal nachsehen.

@bronger Ich denke, @cpuguy83 hat die richtige Frage gestellt, wie würden Sie das lösen, wenn Sie 'cp' verwenden würden? Ich habe nachgesehen und keine Art von Ausschlussoption auf „cp“ bemerkt, daher bin ich mir nicht sicher, wie Sie dies auch außerhalb eines „Docker-Builds“ lösen würden.

Mit CP-Verhalten könnte ich die Situation verbessern, indem ich sage

COPY ["A1", ... "A10", "/some/where/"]

Es ist immer noch ein leichtes Wartungsproblem, weil ich an diese Zeile denken müsste, wenn ich ein "A11"-Verzeichnis hinzufügen würde. Aber das wäre akzeptabel.

Außerdem benötigt cp keine Ausschlüsse, da das Kopieren von allem und das Entfernen der unerwünschten Teile fast keine Auswirkung auf die Leistung hat, abgesehen vom Kopieren selbst. Mit COPY von Docker bedeutet dies, dass der Cache jedes Mal, wenn B geändert wird, falsch ungültig gemacht wird, und größere Bilder.

@bronger kannst du machen:

COPY a b c d /some/where

so wie du es vorgeschlagen hast.

Was RUN rm ... nach COPY ... betrifft, ja, Sie haben eine zusätzliche Ebene, aber Sie sollten trotzdem in der Lage sein, den Cache zu verwenden. Wenn Sie aufgrund dessen einen Cache-Miss sehen, lassen Sie es mich wissen, ich denke nicht, dass Sie das tun sollten.

Aber

COPY a b c d /some/where/

kopiert den Inhalt der Verzeichnisse abcd zusammen, anstatt die Verzeichnisse /some/where/{a,b,c,d} zu erstellen. Es funktioniert wie rsync mit einem an das src-Verzeichnis angehängten Schrägstrich. Daher die _vier_ Anweisungen

COPY a /some/where/a/
COPY b /some/where/b/
COPY c /some/where/c/
COPY d /some/where/d/

wird gebraucht.

Was den Cache angeht ... wenn ich so sage

COPY . /some/where/
RUN rm -Rf /some/where/e

dann wird der Cache nicht verwendet, wenn sich e ändert, obwohl e nicht effektiv in die Operation einbezogen wird.

@bronger ja, leider hast du recht. Ich schätze, wir könnten ein Flag vom Typ --exclude zzz hinzufügen, aber laut https://github.com/docker/docker/blob/master/ROADMAP.md#22 -dockerfile-syntax wird es vielleicht nicht viel Traktion jetzt.

Meinetwegen. Dann werde ich vorerst ein COPY+rm verwenden und einen FixMe-Kommentar hinzufügen. Vielen Dank für Ihre Zeit!

Nur zu :+1: dieser Ausgabe. Ich bedauere regelmäßig, dass COPY die nachgestellte Slash-Semantik von rsync nicht widerspiegelt. Dies bedeutet, dass Sie nicht mehrere Verzeichnisse in einer einzigen Anweisung KOPIEREN können, was zu einer Schichtvermehrung führt.

Ich stoße regelmäßig auf einen Fall, in dem ich viele Verzeichnisse kopieren möchte, außer einem (das später kopiert wird, weil ich möchte, dass es unterschiedliche Layer-Invalidierungseffekte hat), also wäre --exclude auch nützlich.

Außerdem ab man rsync :

       A trailing slash on the source changes this behavior to avoid  creating
       an  additional  directory level at the destination.  You can think of a
       trailing / on a source as meaning "copy the contents of this directory"
       as  opposed  to  "copy  the  directory  by name", but in both cases the
       attributes of the containing directory are transferred to the  contain‐
       ing  directory on the destination.  In other words, each of the follow‐
       ing commands copies the files in the same way, including their  setting
       of the attributes of /dest/foo:

              rsync -av /src/foo /dest
              rsync -av /src/foo/ /dest/foo

Ich denke, es kann jetzt nicht geändert werden, ohne viele wilde Dockerfile s zu brechen.

Nehmen wir als konkretes Beispiel an, ich habe ein Verzeichnis, das so aussieht:

/vendor
/part1
/part2
/part3
/...
/partN

Ich möchte etwas, das so aussieht:

COPY /vendor /docker/vendor
RUN /vendor/build
COPY /part1 /part2 ... /partN /docker/ # copy directories part1-N to /docker/part{1..N}/
RUN /docker/build1-N.sh

Damit part1-N das Erstellen von /vendor nicht ungültig macht. (da /vendor im Vergleich zu part1-N selten aktualisiert wird).

Ich habe dies zuvor umgangen, indem ich part1-N in ein eigenes Verzeichnis gestellt habe, also:

/vendor
/src/part1-N

Dieses Problem kenne ich aber auch von Projekten, die ich nicht so einfach umstellen kann.

@praller gutes Beispiel, wir stehen vor genau dem gleichen Problem. Das Hauptproblem ist, dass go's filepath.Match im Vergleich zu regulären Ausdrücken nicht viel Kreativität zulässt (dh kein Anti-Muster).

Ich habe mir gerade einen etwas hirnrissigen Workaround dafür ausgedacht. COPY kann keine Verzeichnisse ausschließen, aber ADD _can_ expand tgz.

Es ist ein zusätzlicher Build-Schritt:
tar --exclude='./deferred_copy' -czf all_but_deferred.tgz .
Docker-Build ...

Dann in Ihrem Dockerfile:
HINZUFÜGEN ./all_but_deferred.tgz /application_dir/
.. Zeug in den selten wechselnden Schichten ..
HINZUFÜGEN . /application_dir/
.. Zeug in den oft wechselnden Schichten

Das gibt die vollständige Syntax von tar zum Einschließen/Ausschließen/was auch immer ohne verschwendete Schichten, die versuchen, einzuschließen/auszuschließen.

@jason-kane Das ist ein netter Trick, danke fürs Teilen. Ein kleiner Punkt: Es sieht so aus, als könnten Sie das Flag z (gzip) nicht zu tar hinzufügen – es ändert den sha256-Prüfsummenwert, wodurch der Docker-Cache ungültig wird. Ansonsten funktioniert dieser Ansatz bei mir super.

+1 für dieses Problem, ich denke, es könnte auf die gleiche Weise unterstützt werden, wie es viele Glob-Bibliotheken unterstützen:

Hier ist ein Vorschlag, alles außer node_modules zu kopieren

COPY . /app -node_modules/

Ich stoße auch auf das gleiche Problem, und es ist ziemlich schmerzhaft für mich, wenn meine Java-Webapps etwa 900 MB groß sind, aber fast 80 % davon selten geändert werden.
Es ist ein früher Zustand meiner Anwendung und die Ordnerstruktur ist einigermaßen stabil, daher macht es mir nichts aus, 6-7 COPY-Layer hinzuzufügen, um den Cache verwenden zu können, aber es wird auf lange Sicht sicherlich weh tun, wenn immer mehr Dateien und Verzeichnisse vorhanden sind sind hinzugefügt

👍

Ich habe das gleiche Problem, obwohl ich mit docker cp alle Dateien aus einem Ordner bis auf eine kopieren möchte

Genau das gleiche Problem hier. Ich möchte ein Git-Repo kopieren und das .git-Verzeichnis ausschließen.

@oaxlin Sie könnten dafür die Datei .dockerignore verwenden.

@antoineco bist du sicher, dass das funktioniert? Es ist schon eine Weile her, seit ich es versucht habe, aber ich bin mir ziemlich sicher, dass .dockerignore zumindest damals nicht mit docker cp funktioniert hat

@kkozmic-seek absolut sicher :) Aber der docker cp CLI-Unterbefehl, den Sie erwähnt haben, unterscheidet sich von der COPY -Anweisung in der Dockerfile, die den Umfang dieses Problems darstellt.

docker cp hat tatsächlich nichts mit Dockerfile und . dockerignore, wird aber andererseits nicht zum Erstellen von Images verwendet.

Würde das auch wirklich mögen - um den Build zu beschleunigen, könnte ich einige Ordner in frühere Teile des Builds kopieren und dann würde mir der Cache helfen ...

Ich bin mir nicht sicher, ob ich den Anwendungsfall verstehe, aber würde das Problem nicht einfach durch Berühren der auszuschließenden Dateien vor COPY gelöst?

RUN touch /app/node_modules
COPY . /app
RUN rm /app/node_modules

AFAIK COPY überschreibt keine Datei, weshalb ich denke, dass dies funktionieren könnte.

Hoppla, vergiss das, es sieht so aus, als würde COPY tatsächlich Dateien überschreiben. Ich bin jetzt etwas verwirrt von https://nodejs.org/en/docs/guides/nodejs-docker-webapp/ was npm installiert und dann ein COPY . /usr/src/app macht. Ich schätze, es geht davon aus, dass node_modules vom Docker ignoriert wird? Andererseits könnte ein Befehl COPY_NO_OVERWRITE (besserer Name erforderlich) eine Möglichkeit sein, Dateien während des Kopierens zu ignorieren (Sie müssten leere Dateien/Verzeichnisse für Dinge erstellen, die Sie ignorieren möchten).

FWIW, ich finde das sehr hässlich.

Ich habe eine andere Hack-Lösung gefunden:

Beispiel Projektstruktur:
Anwendung/
Konfiguration/
Skript/
spez./
statisch/
...

Wir wollen:

  1. Statisch kopieren/
  2. Kopieren Sie andere Dateien
  3. App kopieren/

Hack-Lösung:
ADD ./static /home/app
ADD ["./[^s^a]*", "./s[^t]*", "/home/app/"]
ADD ./app /home/app

Das zweite ADD ist äquivalent zu: Alle kopieren, außer "./st " und "./a ".
Irgendwelche Ideen für Verbesserungen?

Welchen Status hat der Kommentar ?

👍

👍

👍

👍

Was ist mit einer .dockerignore-Datei auf die gleiche Weise wie .gitignore?

@mirestrepo Sehen Sie sich die ersten beiden Folgemaßnahmen zu dieser Ausgabe an.

Derzeit ist dies ein Mega-Perf-Nerf für die C# / Dotnet-Entwicklung.

Was ich will:

  • Kopieren Sie zuerst alle externen DLLs in die Docker-Images (alles außer My*.dll)
  • Kopieren Sie dann alle meine DLLs (beginnend mit My.*.dll).

Jetzt scheint es, dass dies nicht (einfach) möglich ist, weil ich nicht alles kopieren kann, außer.

Entweder werden DLLs doppelt kopiert, was die Docker-Dateigröße erhöht, oder alles wird in einer Ebene kopiert.
Letzteres ist ein Mega-Nerf, da externe DLLs jedes Mal kopiert werden, anstatt zwischengespeichert zu werden.

@adresdvila danke für die Lösung, in die ich es aufteilen konnte:

COPY ["[^M][^y]*","/app/"] 
COPY ./My* /app/

Obwohl dies immer noch das Problem hinterlässt, dass .json-Dateien beim ersten Befehl kopiert werden

Ich melde mich nur, um mich bei @antoineco zu bedanken, mein Problem ist gelöst. Ich kopiere das .git-Verzeichnis nicht mehr in meine Docker-Images.

Dadurch wurde die Bildgröße dramatisch verbessert und mein Bild ist viel freundlicher für das Docker-Caching-System.

Ich habe das gleiche Problem. Ich habe eine große Datei, die ich vor den restlichen Dateien kopieren möchte, damit jede Änderung im Kontext sie nicht wiederholt, da das Kopieren viel Zeit in Anspruch nimmt (7-GB-BIN-Datei). Gibt es neue Workarounds?

Das Problem beim COPY-and-Prune-Ansatz besteht darin, dass die Ebene vor dem Pruning weiterhin alle Daten enthält.

COPY . --exclude=a --exclude=b wäre extrem nützlich. Was denkst du, @cpuguy83?

@Nowaker gefällt mir. Scheint sowieso mit tar und rsync übereinzustimmen.
Ich denke, dies sollte das gleiche Format wie dockerignore unterstützen?

@tonistiigi @dnephin

Dieser Fall würde von #32507 behandelt werden, denke ich.

@ cpuguy83 Ja. Vor allem im Einklang mit COPY --chown=uid:gid

@dnephin RUN --mount klingt nach einem völlig anderen Anwendungsfall, bei dem es darum geht, etwas basierend auf Daten zu generieren, die wir nicht benötigen, nachdem die Ausgabe generiert wurde. (zB Kompilieren mit Go, Generieren von HTMLs aus Markdown-Datei usw.). RUN --mount ist dope und ich würde es definitiv in dem Projekt verwenden, an dem ich gerade arbeite (Generieren von API-Dokumenten mit Sphinx).

COPY somedir --exclude=excludeddir1 --exclude=excludeddir2 konzentriert sich auf das Kopieren von Daten, die im Bild landen müssen, aber auf mehrere COPY-Anweisungen verteilt sind, nicht nur auf eine. Das Ziel ist es, explizit COPY first second third .... eleventh destination/ zu vermeiden, wenn das Projekt viele Verzeichnisse im Stammverzeichnis hat und Änderungen/Erweiterungen unterliegen.

In meinem Fall möchte ich die meisten Dateien kopieren, mit Ausnahme derer, die nicht unbedingt erforderlich sind, um sicherzustellen, dass der Cache verwendet wird, wenn sich die Quelldateien nicht geändert haben. Dann kompilieren/generieren Sie - und verwenden Sie den Cache, wenn sich die kopierten Dateien nicht geändert haben (yay). Kopieren Sie ganz am Anfang die Dateien, die ich zuvor ausgeschlossen habe und die sich möglicherweise seit dem vorherigen Build geändert haben, aber ihre Änderung wirkt sich nicht auf das Kompilieren/Generieren aus. Offensichtlich habe ich eine Tonne Dateien und Verzeichnisse in . die ich zuerst KOPIEREN möchte, und nur ein paar, die ich irgendwo am Ende KOPIEREN möchte.

Die Idee ist, dass RUN --mount viele Probleme lösen kann. COPY --exclude löst nur ein einziges Problem.

Ich würde lieber etwas hinzufügen, das viele Probleme löst, als einen Haufen Syntax hinzuzufügen, um einzelne Probleme zu lösen. Sie würden RUN --mount... rsync --exclude ... (oder ein Skript, das einzelne Dinge kopiert) verwenden und es wäre das Äquivalent zu COPY --exclude .

@dnephin Oh, ich habe nicht an RUN --mount rsync gedacht! Exzellent! 👍

Das ist wirklich ausgezeichnet. Sie können das Caching jedoch nicht effizient nutzen @Nowaker , da der Cache ungültig wird, wenn sich etwas im gemounteten Verzeichnis ändert, nicht nur das, was Sie rsyncen möchten.

Wenn Sie die Ausgabe dieses rsync als Eingabe für etwas anderes verwenden und dort tatsächlich keine Dateien geändert wurden, wird der Cache wieder aufgenommen. Wenn Sie wirklich Lust darauf haben, können Sie dies derzeit mit etwas wie https://gist.github.com/tonistiigi/38ead7a4ed60565996d207a7d589d9c4#file -gistfile1-txt-L130-L140 tun. Die einzige Änderung in RUN --mount (oder LLB im Buildkit) besteht darin, dass Sie Dateien zwischen den Phasen nicht kopieren müssen, sondern direkt darauf zugreifen können, sodass es viel schneller geht.

Wie wäre es mit https://docs.docker.com/develop/develop-images/multistage-build/?

FROM php:7.2-apache as source
COPY ./src/ /var/www/html/
RUN rm -rf /var/www/html/vendor/
RUN rm -rf /var/www/html/tests/

FROM php:7.2-apache
COPY --from=source /var/www/html/ /var/www/html/

@antoineco Welp, dann ist es nicht mehr exzellent. Danke für den Hinweis..

@MartijnHols Dies ist eine gute Problemumgehung. Danke fürs Schreiben.

An die Betreuer: Das heißt, wir könnten sagen: "Warum --chown in COPY implementieren, Sie können RUN chown in einem mehrstufigen Build verwenden". Wir brauchen --exclude für geistige Gesundheit. Heutzutage gibt es zu viele Problemumgehungen in Dockerfiles.

Ich habe einen Anwendungsfall, der von COPY --exclude profitieren würde. Ich habe einen großen Datenordner, der vollständig in den Container kopiert werden muss. Der Inhalt dieses Verzeichnisses unterliegt häufigen Änderungen. Um die Cache-Leistung zu verbessern, gibt es eine einzelne große Datei im Verzeichnis, die ich in eine eigene Ebene kopieren möchte, bevor ich den Rest kopiere. Ab sofort ist es unnötig ausführlich, diesen Containertyp zu beschreiben.

Was ist die richtige Art und Weise, Layered Caching zu verwenden, das sich um die requirements.txt dreht

Ich habe das:

/root-app
 - /Dockerfile
 - /requirements.txt
 - /LICENSE
 - /helloworld.py
 - /app-1
     -/app-1/script1
     -/app-1/script2
     -/app-1/script3
 - /app-2
     -/app-2/script1

Und Dockerfile:

FROM python:slim
COPY ./requirements.txt /
RUN pip install --trusted-host pypi.python.org -r /requirements.txt
WORKDIR /root-app
COPY . /helloworld
CMD ["python", "helloworld.py"]

Was ist der richtige Weg, um den zweiten COPY-Befehl zu verwenden, um den Anforderungs-Build-Cache auszuschließen ... und meine App-1 und App-2 auf ähnliche Weise zu schichten, wenn sie sich nicht stark ändern?

@axehayz Ich bin mir nicht sicher, ob Sie das fragen, aber ich würde etwas Ähnliches wie den Knoten-Workflow in https://medium.com/@guillaumejacquart/node -js-docker-workflow-12febcc0eed8 tun.

Das heißt, es ist in Ordnung, wenn Ihre zweite Kopie nur COPY . ; solange Ihr pip install davor steht, werden die zwischengespeicherten für die installierten Pakete nicht ungültig.

Stand vor dem gleichen Problem. Im Moment würde ich es vorziehen, die Dateien in verschiedenen Verzeichnissen zu entpacken.

Ich habe einen anderen Fall für COPY --exclude=... --exclude=...

Ich versuche, ein COPY --from=oldimage zu machen, um meine Bildgröße zu reduzieren, und ich muss die meisten Dateien kopieren, aber ohne einige von ihnen. Ich kann es Verzeichnis für Verzeichnis tun, was schmerzhaft ist, aber funktioniert ... Aber in der Lage zu sein, entweder eine Liste von Verzeichnissen/Dateien auszuschließen oder mehrere --exclude-Optionen bereitzustellen, wäre so viel besser und einfacher zu warten.

Also nach dreieinhalb Jahren gar keine Anerkennung?

@asimonf Es gibt jede Menge Anerkennung und Hin und Her, um den Anwendungsfall zu verstehen. Ich nehme an, Sie meinen, niemand hat diese Arbeit gemacht? Das ist richtig. Wir alle müssen Entscheidungen über die Dinge treffen, an denen wir arbeiten.

Ehrlich gesagt kann dies ziemlich einfach mit vorhandener Funktionalität durchgeführt werden, auch wenn dies bedeutet, dass Sie ein wenig mehr in Ihr Dockerfile schreiben müssen, um dies zu erreichen.

# haven't tested exact syntax, but this is the general idea
FROM myRsync AS files
COPY . /foo
RUN mkdir /result && rsync -r --exclude=<pattern> /foo/ /result/

FROM scratch
COPY --from=files /result/* /

Mit Buildkit benötigen Sie nicht einmal eine zusätzliche Bühne

#syntax=docker/dockerfile:experimental
..
RUN --mount=target=/ctx rsync ... /ctx/ /src/

Wenn mir nicht etwas fehlt, scheint die Verwendung eines mehrstufigen Builds hier nicht die Lösung zu sein. Der Cache wird in der COPY-Phase immer noch ungültig gemacht.

Wenn mir nicht etwas fehlt, scheint die Verwendung eines mehrstufigen Builds hier nicht die Lösung zu sein. Der Cache wird in der COPY-Phase immer noch ungültig gemacht.

Das ist richtig. Da es das Problem ist, das ich gerade habe.

Mehrstufig funktioniert bei mir super.

Ich unterteile meinen Build in mehrere Stufen, um den Cache vollständig zu nutzen, sieht er ungefähr so ​​​​aus:

FROM alpine as source

WORKDIR /app
COPY . ./
RUN scripts/stagify-files

FROM node:12.4.0

WORKDIR /app

# Step 0: Setup environments
COPY --from=source /app/stage0 ./
RUN stage0-build.sh

# Step 1: Install npm packages
COPY --from=source /app/stage1 ./
RUN stage1-build.sh

# Step 2: Build project
COPY --from=source /app/stage2 ./
RUN stage2-build.sh

@zenozen Die Herausforderung bei diesem Prozess besteht darin, dass Sie Ihr Anwendungslayout speziell für einen Docker-Build anordnen mussten, was viele Leute nicht tun möchten.
Die Verwendung von Docker ist eine von vielen Überlegungen, die bei der Gestaltung Ihrer Bewerbungsdateien (z. B. Wartbarkeit, Benutzerfreundlichkeit für neue Mitarbeiter, projektübergreifende Standards, Framework-Anforderungen usw.) abzuwägen sind.

@cfletcher Ich bin mir nicht sicher, ob ich ganz verstehe, was du meinst.

Für die oben erwähnte Änderung habe ich meine Docker-Datei tatsächlich in ein Unter-Unter-Verzeichnis verschoben (was mir viele Probleme verursachte, als ich versuchte, diese Dateien mit rsync zu stagnieren), was bedeutet, dass ich versuchte, meine Docker-Datei zu verstecken.

Der von mir vorgeschlagene Ansatz ist allgemein, wie ich mir vorstelle. Angenommen, Sie haben 100 Dateien in Ihrem Projekt. Es wählt einfach 1 von ihnen aus, um Stufe 0 zu erstellen, dann 1 + 10 von ihnen, um Stufe 1 zu erstellen, und dann alle 100, um Stufe 2 zu bilden. Jede Stufe wird auf die vorherige gestapelt und hat einen anderen Build-Befehl. Bei einer komplizierten Projektstruktur bedeutet dies nur, dass die Logik der Stagify-Dateien kompliziert wäre.

Für mich ist der Hauptgrund, dass ich meinen Code in Module aufteile und alle package.json Dateien kopieren muss, bevor ich $#$1 npm install #$ ausführe.

Möchte auch eine Art Ausschlussargument für die Kopie. Wir haben mehr als 20 Dateien und mehr als 10 Verzeichnisse im Stammverzeichnis. Wir codieren stark auf 2 der Verzeichnisse und ein paar der Dateien. Ich möchte diese in zwei COPY-Ebenen aufteilen. Eine für die statischen Dateien und Verzeichnisse, die wir nie berühren, und die andere für die Dateien und Verzeichnisse, die wir immer berühren.

Es ist sehr traurig, dass dies immer noch ignoriert wird. Dies hätte mir geholfen, 5 Minuten pro Build zu sparen, wenn ich EIN Verzeichnis ausschließen könnte, um den Cache nicht ungültig zu machen.

Mit Buildkit ist der Cache nicht vom übergeordneten Image abhängig, da es sich um ein Pre-Buildkit handelt.
Also ja, mit der erwähnten rsync-Lösung werden Sie einen Treffer erzielen, da Sie jedes Mal synchronisieren müssen, wenn sich etwas ändert, aber nachfolgende Phasen werden basierend auf dem Inhalt zwischengespeichert, und wenn der Inhalt dessen, was übertragen wird, dann nicht geändert wird. .. zumindest in meiner vollständigen Theorie vor Ort sollten diese Stufen den Cache verwenden.

Es ist traurig, dass das Hinzufügen eines einfachen --exclude -Flags zu COPY so schwer zu verkaufen ist. Es gehört zu den TOP30-Tickets mit den meisten positiven Stimmen und ist im Vergleich zu anderen TOP30-Tickets relativ einfach zu implementieren. :(

Es ist nicht umstritten, es erfordert Arbeit.

@ cpuguy83 Yay. Es sah umstritten / etwas abgelehnt aus. Bedeutet das, dass eine ordentliche PR mit COPY --exclude wahrscheinlich akzeptiert würde, wenn sie die Qualitätsstandards erfüllt?

Ich kann nicht für jeden Betreuer sprechen, aber ich habe vor ungefähr einem Monat mit @tonistiigi darüber gesprochen und IIRC die größte Hürde, wie dies mit Dockerignore, der Syntax usw. zusammenhängt (und die Tatsache, dass Dockerignore syntaktisch unzureichend ist).

Die Änderung müsste in Buildkit gehen.

Upvoting COPY --exclude=... --exclude=... - auch in meinem Fall eines Monolith-Repos erforderlich

Upvoting! Ich habe es mit COPY !(excludedfile) . versucht, was auf Bash funktionieren sollte, aber nicht auf Docker

Ich mag die Vorschläge nicht, alles in der Datei .dockerignore für jede COPY Anweisung in der Dockerfile wiederholen zu müssen. In der Lage zu sein, TROCKEN zu bleiben mit dem, was ein Teil des Bildes sein wird und nicht, sollte meiner Meinung nach eine Priorität sein.

Wenn ich mir #33923 ansehe, glaube ich nicht, dass es Zufall ist, dass das, was Sie aus dem Build-Kontext ausschließen möchten, genau die gleichen Dinge sind, die Sie aus COPY -Anweisungen ausschließen möchten. Ich glaube so etwas wäre eine gute Lösung:

COPY --use-dockerignore <source> <target>

Oder vielleicht sogar so etwas:

COPY --use-ignorefile=".gitignore" <source> <target>

Wenn man sieht, dass .dockerignore normalerweise bereits eine 90%ige Reproduktion von .gitignore ist, ist es besonders ärgerlich, jede ignorierte Datei und jeden ignorierten Ordner noch einmal für jede einzelne COPY -Anweisung wiederholen zu müssen. Es muss einen besseren Weg geben.

@asbjornu .gitignore und .dockerignore sind überhaupt nicht dasselbe. Insbesondere für mehrstufige Builds, bei denen Artefakte auf einer Build-Stufe generiert werden und überhaupt nicht in Git vorhanden sind, sollten sie dennoch in das resultierende Image aufgenommen werden.
Und ja, mit eingeführten mehrstufigen Builds SOLLTE die Möglichkeit bestehen, verschiedene .dockerignore-Dateien pro Stufe zu verwenden - absolut.

Ich möchte oft außerhalb von "Docker Build" kopieren. In diesen Fällen tut .dockerignore nichts. Wir brauchen eine Änderung an "docker cp", das ist die einzig vernünftige Lösung

Es ist 5 Jahre her, dass diese Ausgabe geöffnet wurde. Im September 2020 will ich das immer noch. Viele Leute haben Hacks zur Problemumgehung vorgeschlagen, aber fast alle von ihnen und andere haben in irgendeiner Form eine exclude -Flagge angefordert. Bitte lassen Sie dieses Problem jetzt nicht länger ungelöst.

Wenn Sie etwas wollen, müssen Sie daran arbeiten oder jemanden finden, der daran arbeitet.

Wenn Sie etwas wollen, müssen Sie daran arbeiten oder jemanden finden, der daran arbeitet.

Zuerst müssen wir wissen, ob Upstream dies will.

Nach der Überprüfung des Quellcodes sollten wir meiner Meinung nach zunächst die Kopierfunktion hier https://github.com/tonistiigi/fsutil/blob/master/copy/copy.go erweitern. Danach können wir backend.go in libsolver erweitern, und erst danach wird es möglich sein, AST und Frontend des Buildkits zu erweitern.
Aber danach wird die Kopie der rsync-Semantik ähnlicher sein als Unix-CP.

UPDATE: Ja, nach dem Erweitern von copy.go wird alles in der Nähe von https://github.com/moby/buildkit/pull/1492 sein, plus Parsing-Liste der Ausschlüsse.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen