Moby: Erlaube die Angabe einer Dockerdatei als Pfad, nicht als Piping.

Erstellt am 8. Okt. 2013  ·  160Kommentare  ·  Quelle: moby/moby

Wäre schön, docker build -t my/thing -f my-dockerfile . angeben zu können, damit ich Dateien HINZUFÜGEN und auch mehrere Dockerfiles haben könnte.

Hilfreichster Kommentar

Also docker build -f Dockerfile.dev . ? edit: ja

Alle 160 Kommentare

Ich habe das gerade untersucht

Verwendung: docker build [OPTIONEN] PATH | URL | -

also wenn du rennst

docker build -t my/thing my-dockerfile

beschwert sich, dass die tar-Datei zu kurz ist.

Es scheint mir, dass die Option 'PFAD' nicht dokumentiert ist, also könnte sie eine veraltete Bedeutung haben?

Also - ich frage mich, ob ich feststellen kann, ob PATH eine Datei ist und keine Tarfile.

Persönlich habe ich eine Reihe von Dockerfiles, die ich zum Testen verwende, und würde sie lieber alle in einem Verzeichnis haben und auch einen vollständigen Kontext haben.

Dieser PATH bezieht sich auf ein Verzeichnis, nicht auf eine bestimmte Dockerfile.

oh, und dann tars dieses Verzeichnis, um es an den Server zu senden - cool!

so ist es möglich, isafile zu erkennen, das Verzeichnis zu tarnen und dann das Dockerfile in diesem Tarball durch die angegebene Datei zu ersetzen.

oder verwenden Sie -f auf die gleiche Weise - damit Ihre Dockerfile-Definitionen getrennt von der Nutzlast leben

Jetzt um herauszufinden, wie die Tests funktionieren, probieren Sie es aus und sehen Sie, ob es für mich funktioniert

Es tarnt nichts - der PATH ist ein Verzeichnis, in dem angenommen wird, dass es ein Dockerfile

das ist nicht alles, was es mit diesem PATH tut - beim Lesen des Codes wird der 'Kontext' an den Server gesendet, indem das Verzeichnis tariert wird.

(ok, ich weiß immer noch nicht, wie es geht, und ich lese den Code erst seit ein paar Minuten, also nimm es mit einem Körnchen Skepsis)

Korrekt, alle nicht entfernten Dateien, auf die über ADD verwiesen wird, müssen sich auch in demselben Verzeichnis befinden, sonst kann der Daemon nicht darauf zugreifen.

Ah, ich verstehe, was Sie sagen - ja - das ist genau das, was ich will - eine Möglichkeit, eine Dockerdatei mit -f anzugeben, und dann das Verzeichnis PATH, das möglicherweise separat ist.

also könnte ich haben:

docker build -t my/thing fooproj
docker build -t my/thing -f debug-dockerfile fooproj

2108 (Hinzufügen einer Include-Direktive zu Dockerfiles) fügt eine interessante Falte hinzu

sollte das Include relativ zum angegebenen Dockerfile oder dem PATH sein. aber noch nicht wichtig.

Spaß:

docker build -t my/thing fooproj
docker build -t my/thing -f ../../debug-dockerfile fooproj
docker build -t my/thing -f /opt/someproject/dockerfiles/debug-dockerfile fooproj

als zusätzlicher Bonus - es gibt noch keine CmdBuild-Tests, also ratet mal, was ich zuerst lernen kann :)

@SvenDowideit arbeitest du daran? Ich dachte daran, vielleicht heute darauf zu hacken

Ich mache mich langsam mit dem Code vertraut und lege los, also mach es - es macht mir zu viel Spaß, nur die Unit-Tests zu schreiben (vielleicht kannst du die Testing-Commits verwenden, um zu helfen :)

Ich werde tun :)

Diese Funktion würde ich auch gerne sehen. Wir haben ein System, das in 3 verschiedenen Modi ausgeführt werden kann, und wir möchten 3 verschiedene Container bereitstellen – einen für jeden Modus. Das bedeutet 3 praktisch identische Docker-Dateien, wobei nur die CMD unterschiedlich ist. Aber da die Pfade nur Verzeichnisse sind und die Verzeichnisse der Kontext für ADD-Befehle sind, kann ich dies jetzt nicht zum Laufen bringen.

Also: +1 von mir!

Scheint, als hätte dies das gleiche Endziel wie #1618 (wenn auch mit anderen Ansätzen). Die Idee dabei ist, ein einzelnes Dockerfile mit mehreren TAG Anweisungen zu verwenden, die zu mehreren Images führen, im Gegensatz zu mehreren Dockerfiles und einem Include-System, wie hier beschrieben. Die Gedanken?

Es scheint, als ob Sie auch einen Pfad angeben können, wenn Sie ein Dockerfile über die Pipe einleiten können. Interessiert, was aus #1618 kommt, aber ich denke, dies bietet viel mehr Möglichkeiten.

Ich war von der Tatsache überrascht, dass in der Dokumentation nicht klar angegeben ist, dass das Verzeichnis, das die Dockerfile-Datei enthält, der Build-Kontext ist - ich habe die falsche Annahme getroffen, dass der Build-Kontext das aktuelle Arbeitsverzeichnis ist, also wenn ich stattdessen einen Pfad zum Docerfile übergeben habe davon, dass es sich im aktuellen Verzeichnis befindet, wurden Dateien, die ich versucht habe, aus dem aktuellen Arbeitsverzeichnis hinzuzufügen, mit den Fehlern "keine solche Datei oder dieses Verzeichnis" bombardiert.

Ich erhalte den gleichen Fehler, Any Ideas

Docker-Build Dockerfile


Kontext hochladen

11.12.2013 21:52:32 Fehler: Fehlerbuild: Tarball zu kurz

@bscott versuche es stattdessen mit docker build . . Build benötigt ein Verzeichnis, keine Datei, und das ist der "Build-Kontext". :)

Hat funktioniert Thx!, ich möchte nur zwischen verschiedenen Docker-Dateien wählen.

+1 von mir.

Ich muss mehrere Bilder aus meiner Quelle erstellen. Jedes Bild ist ein separates Anliegen, für das derselbe Kontext erstellt werden muss. Das Verschmutzen einer einzelnen Dockerfile (wie in # 1618 vorgeschlagen) ist seltsam. Es wäre viel sauberer für mich, 3 separate <image-name>.docker Dateien in meiner Quelle zu behalten.

Ich würde mich freuen, wenn so etwas umgesetzt würde.

Dies ist schwieriger umzusetzen, als es auf den ersten Blick erscheinen mag. Es scheint, dass ./Dockerfile ziemlich eingebrannt ist. Nach der ersten Untersuchung sind zumindest diese Dateien beteiligt:

api/client.go
archive/archive.go
buildfile.go
server.go

Das client verwendet archive um build context archive zu tarieren und an das server senden, das dann archive , um build context zu enttarnen und übergeben Sie die Bytes an buildfile .

Die einfachste Implementierung scheint die Änderung von client und archive zu beinhalten, um die ./Dockerfile tar mit der über diese Option angegebenen Datei zu überschreiben. Ich werde weiter recherchieren.

@thedeeno Ich schaue ganz schnell nach und zeige dir, wo die Änderung vorgenommen werden sollte. Ich denke, es ist nur an einer Stelle.

+1 von mir!

Ich habe sowohl #1618 als auch #2112 verfolgt und dies ist die eleganteste Lösung.

Es gibt einen besonderen Anwendungsfall in meiner Entwicklung, bei dem diese Funktion unglaublich praktisch wäre... Wenn Sie an Anwendungen arbeiten, die sowohl eine "Web"- als auch eine "Worker"-Rolle haben. Ich möchte für diese Situation zwei Dockerfiles erstellen "Dockerfile-web" und "Dockerfile-worker". Ich könnte dann beide erstellen, sie mit Tags versehen und in mein Image-Repository verschieben. Ich würde dann mehrere Web-Front-End-Instanzen hinter einem Load-Balancer und mehreren Workern ausführen, um die Aufgaben zu bearbeiten, die in die Warteschlangen verschoben werden.

+1 als Alternative zu #2745.

+1

Ich war erstaunt, dass Dockerfile hartcodiert ist und dass der Build-Kontext gezwungen ist, das Verzeichnis des Dockerfiles zu sein und selbst mit Befehlszeilen-Flags nicht überschrieben werden kann. Dies schränkt die Nützlichkeit und Flexibilität von Docker als Entwicklungs-, Test- und Bereitstellungstool stark ein.

+1
Ich würde mich über diese Änderung freuen

+1
Brauche das wirklich.

5033 sollte diese Funktion zulassen. cc/@crosbymichael

@shykes was

Ich zögere.

Einerseits möchte ich nicht die Möglichkeiten der Leute einschränken, ihren Build anzupassen.

Auf der anderen Seite mache ich mir Sorgen, dass dasselbe passieren wird wie bei _run -v /host:/container_ und _expose 80:80_. Mit anderen Worten, es wird den 1%, die wissen, was sie tun, ermöglichen, eine coole Anpassung hinzuzufügen - und die anderen 99% schießen sich dann ziemlich schlecht in den Fuß.

Wir haben beispielsweise viele neue Docker-Benutzer, die mit Host-Mount-Volumes anstelle von regulären Volumes beginnen. Und wir mussten die _expose 80:80_-Syntax komplett ablehnen, weil zu viele Leute ohne triftigen Grund Bilder veröffentlichten, die nicht mehr als einmal pro Host ausgeführt werden konnten.

Meine Frage ist also: riskieren wir nicht, viele Quell-Repositorys zu haben, die mit _docker build nicht wiederholbar erstellt werden können?

_, denn jetzt müssen Sie eine README lesen, die Ihnen sagt, dass Sie ein Shell-Skript ausführen sollen, das dann 'docker build -f ./path/to/my/dockerfile' ausführt, einfach weil Sie keine Lust hatten, ein Dockerfile an die Wurzel des Repositorys? Oder vielleicht, weil Sie ein Anfänger sind und diese Technik einfach aus einem inoffiziellen Tutorial kopiert haben?

Die Möglichkeit, ein Quell-Repository zu löschen und es automatisch ohne Mehrdeutigkeit oder menschliche Entdeckung erstellen zu lassen, ist einer der Gründe, warum Dockerfiles nützlich sind. Bringt dieser Pull-Request nicht das Risiko mit sich, in vielen Fällen ohne triftigen Grund einzubrechen?

@shykes Ich

  1. Ich habe eine Docker-basierte Build-Umgebung, die ein Artefakt erzeugt (in diesem Fall eine JAR-Datei). Die Build-Umgebung unterscheidet sich von der Ausführungsumgebung (andere Abhängigkeiten, größeres Image usw., daher möchte ich die Build-Umgebung nicht in die Laufzeit übernehmen. Für mich ist es am sinnvollsten, den Dockerfile Build zu haben und führe die Laufzeitumgebung um das JAR herum aus. Also habe ich eine separate Dockerfile.build Datei, die die Build-Umgebung erstellt und ausführt und die JAR erstellt. Aber da ich das Dockerfile nicht angeben kann, musste ich ein scripts/build erstellen docker build < Dockerfile.build scripts/build Datei ausführt und dann das Host-Volume mit docker run -v ... mountet, um den Build auszuführen (da ich ADD mit eingepfeiften Dockerfiles nicht verwenden kann). Ich möchte stattdessen nur docker build -t foobar/builder -f Dockerfile.build , docker run foobar/builder , docker build -t foobar/runtime , docker run foobar/runtime ausführen und einfach ADD-Befehle in beiden Dockerfiles verwenden.
  2. Mit ONBUILD-Anweisungen möchte ich Dockerfiles in Unterverzeichnisse ablegen (oder Dockerfile.env usw.-Dateien im Stammverzeichnis haben), die das Stamm-Dockerfile in ihrer FROM-Anweisung haben, aber trotzdem das Stammverzeichnis des Projekts als verwenden können ihren Build-Kontext. Dies ist beispielsweise nützlich, um Konfigurationsparameter für verschiedene Umgebungen einzubringen. Das Root-Dockerfile würde immer noch einen nützlichen Container erzeugen, aber die anderen würden andere Varianten erstellen, die wir brauchen.

Ich denke, das, was ich wirklich gerne hätte, ist, die Konzepte "Build-Kontext" von "Dockerfile-Speicherort / -Name" trennen zu können. Natürlich gibt es viele Möglichkeiten, dies zu tun, aber dies scheint mir relativ einfach zu sein.

@cap10morgan Könnten Sie mich auf Ihr Beispiel 1 hinweisen oder auf etwas, das sich dem

@shykes https://github.com/shykes ist dieser Traum von Portabilität nicht genau
wofür ist der Bildindex da? Warum müssen Build-Umgebungen sein?
auch tragbar?

Einige Build-Prozesse erfordern mehr als das, was mit Vanilla möglich ist
Docker-Datei. Darüber hinaus erzwingen Sie ein Dockerfile pro Kontext (was genau das ist)
diese Anfrage soll behoben werden) ist sehr einschränkend.

Das betrifft unser Team sehr. In unserem Setup möchten wir mehrere produzieren
Bilder aus dem gleichen "Kontext". Durch Hinzufügen der Option --file können wir dies tun
was wir wirklich tun wollen - nämlich foo.docker und bar.docker hinzufügen
in unser Repository-Root. Stattdessen schreiben wir Bash-Skripte zum Kopieren
Tonnen von Dateien in temporäre Speicherorte, um einen Kontext herzustellen, und benennen Sie unsere um
benannte Docker-Dateien in die magischen Dockerfile nur damit docker build kann
Arbeit.

Für mich gibt es diese Reifen ohne guten Grund. Wenn jemand aus unserem Team will
Um unsere Bilder zu erstellen, müssen sie benutzerdefinierte Skripte ausführen, um die Arbeit zu erledigen -
genau das, was Sie Ihrer Meinung nach vermeiden können, indem Sie sich an diese Einschränkung halten.

Am Montag, 7. April 2014 um 16:23 Uhr schrieb Solomon Hykes [email protected] :

@cap10morgan https://github.com/cap10morgan jede Chance, die Sie zeigen könnten
mich zu deinem Beispiel 1 oder etwas, das sich dem annähert? Damit ich spielen kann
herum und stellen Sie sicher, dass wir über dasselbe sprechen.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf Gi tHub anhttps://github.com/dotcloud/docker/issues/2112#issuecomment -39778691
.

@shykes, da dies anscheinend "wontfixed" wird, können Sie auf Dokumente oder eine Erklärung der Docker-zertifizierten Methode zur Behebung dieses Problems verweisen?

Mein Anwendungsfall ist, dass ich eine App habe, die ich mit Docker erstellen möchte, bei der die Tests andere Anforderungen haben als ein Produktionsimage. Ich denke, das ist ziemlich üblich.

Dies und das .dockerignore-Problem (https://github.com/dotcloud/docker/pull/3452) (das Kopieren meines gesamten .git-Verzeichnisses in den Build-Kontext) sind die ersten etwas kritischen Punkte, auf die ich beim Ausprobieren von Docker für einen gestoßen bin unserer Projekte in den letzten Tagen und scheinen mir kein Klacks zu sein, aber es scheint einen Gegenpol zu diesen Themen zu geben.

+1, wenn Sie dies auch benötigen - wir haben eine einzige Codebasis mit mehreren Mikrodiensten, die darin entwickelt werden. Wir möchten in der Lage sein, mehrere Bilder zu generieren, zum Beispiel ein Bild mit services/base/* und services/fooservice/* ; und ein weiteres Image mit services/base/* und services/barservices/* und auch staticfiles/*.
Wir können keine Dockerfiles im Serviceordner platzieren, da Docker diesen Ordner dann als Kontext behandelt und wir nichts HINZUFÜGEN können, was höher in der Ordnerstruktur ist. Wir können nicht zwei Dockerfiles in root platzieren, da sie denselben Namen hätten.
Die einzige Lösung, die wir haben, besteht darin, das Dockerfile im Dienstordner zu platzieren und dann ein benutzerdefiniertes Skript zu schreiben, um das ausgewählte Dockerfile zu analysieren, zu bestimmen, welche Pfade hinzugefügt werden sollen (alle relativ zum Projektstamm angegeben), und sie dann in ein neues zu kopieren temporären Ordner, kopieren Sie die ausgewählte Dockerdatei in das Stammverzeichnis dieses neuen Ordners und führen Sie schließlich den "docker build tempfolder" aus. Ist das wirklich notwendig?
Es wäre so viel einfacher gewesen, wenn Sie "docker build" einfach separat mitteilen könnten, wo sich das Dockerfile und wo der Kontext befindet.

Läuft auch auf dieses Problem .. würde gerne eine Art Fix sehen.

+1, die Umgehung dieser Einschränkung ist ein großer Schmerz.

+1 für -f Flag, das den Dockerfile-Pfad unabhängig vom Build-Kontext angibt

Docker ist so ein großartiges Tool, aber diese enge Kopplung von Kontext und spezifischem Dockerfile belastet das Docker-Team definitiv ein wenig. Die Verzeichnisstruktur spiegelt nicht immer die 'Container/Subsystem'-Struktur exakt wider.

Wie schwer kann es sein, es zu reparieren? Und es gab ein paar PRs dafür, aber sie wurden ignoriert.

Eine verwandte einfache Ergänzung besteht darin, eine Ignorier-Datei für Dinge zu haben, die wir nicht zum Kontext hinzufügen möchten - ja, ich sehe dich an, .git ...

Dies könnte mich tatsächlich dazu bringen, Docker vorerst zu überspringen und zu Vagrant + Ansible zurückzukehren. Schön.

@davber .dockerignore ist in -> #6579

Aber ja, das Beitragsmanagement ist im Moment ein bisschen schmerzhaft und eines der seltenen entmutigenden Dinge bei Docker bisher. Ich denke, sie sind nur hoffentlich ein bisschen überfordert.

Docker-Team, wie können Leute so etwas überprüfen und einbinden? Wenn es einen klaren Gedanken darüber gibt, warum dies wirklich schlecht ist und wie Projekte dieses Problem vermeiden sollten, würden wir es gerne hören, aber dies scheint ein einfaches Problem zu beschreiben und ein einfaches Problem zu lösen.

/cc @shykes @creack @crosbymichael @vieux

+1 für -f-Flag. Auch eine DOCKERFILE-Umgebungsvariable zum Überschreiben von Build-Einstellungen.

@jakehow ja, es gibt definitiv ein Element der Überforderung, auf jeden Betreuer gibt es mindestens 1.000 Leute, die aktiv etwas anfordern und eine detaillierte Erklärung verlangen, warum es noch nicht getan wurde. Wir geben wirklich unser Bestes, und wenn Sie die IRC-Kanäle #docker und #docker-dev besuchen, werden Sie die Feuerwehr hautnah miterleben.

Aber in diesem Fall gab es eine klare Antwort, warum es besser ist, die 1-1 Zuordnung von Dockerfile und Quellverzeichnis beizubehalten. Ich wiederhole es noch einmal: Wir wollen die selbstbeschreibende Eigenschaft von Docker-Builds erhalten. Die Tatsache, dass Sie auf ein Quellcodeverzeichnis verweisen können, _ohne weitere Informationen out-of-band_, und daraus ein Image genau nach den Spezifikationen des Upstream-Entwicklers erstellen können, ist sehr mächtig und ein wichtiges Unterscheidungsmerkmal von Docker.

Sicher, das dynamische Kombinieren von Verzeichnis X mit Dockerfile Y im Handumdrehen ist ein wenig praktisch (obwohl ich nie ein brennendes Bedürfnis danach verspürte und Docker viel verwende). Aber es macht es viel zu einfach, etwas Dummes zu tun - nämlich die selbstbeschreibende Natur Ihres Builds zu brechen. Und das scheint ein massiv schlechter Kompromiss zu sein. Daher die Entscheidung, diese Funktion nicht zu implementieren.

Was die Beispiele "1 Quellrepo, mehrere Bilder" betrifft, ja, ich stimme definitiv zu, dass dies erforderlich ist. Was wir brauchen, ist eine Docker-Standardmethode für ein einzelnes Quellverzeichnis, um mehrere Build-Ziele zu definieren. Dies kann mit einem mehrteiligen Dockerfile oder mit mehreren Dockerfiles erfolgen _solange es eine wohldefinierte Dateinamenskonvention gibt, die es ermöglicht, diese Dockerfiles auf eine eindeutige Weise aufzulisten und auszuwählen_.

Wenn jemand dazu beitragen möchte, würden wir es gerne zusammenführen. Und wie immer helfen wir gerne Erstautoren, sagt Hallo im IRC und wir werden euch den Einstieg erleichtern.

@davber Ich hatte den Eindruck, dass Vagrant die gleiche Beschränkung von 1 Beschreibungsdatei pro Projekt hat (vermutlich aus ähnlichen Gründen). Wie löst der Wechsel zurück zu Vagrant Ihr Problem genau?

@gabrtv möchten Sie versuchen, Multi-Image zurückzubringen? Hier ein vorläufiger Vorschlag:

$ ls | grep Dockerfile
Dockerfile
db.Dockerfile
frontend-prod.Dockerfile
frontend-dev.Dockerfile
$ docker build -t shykes/myapp .
Successfully built shykes/myapp/db
Successfully built shykes/myapp/frontend-dev
Successfully built shykes/myapp/frontend-prod
Successfully built shykes/myapp
$ docker build -t shykes/myapp2 --only frontend-dev .
Successfully built shykes/myapp2/frontend-dev

Dieser Vorschlag würde für uns gut funktionieren und ich kann mir vorstellen, dass er auch andere Probleme für andere Menschen löst.

@shykes Ich glaube nicht, dass ich kaufe, dass die Erhöhung der Komplexität des Dockerfile-Formats ein lohnender Kompromiss ist, um bei einem Dockerfile zu bleiben.

Nehmen Sie zum Beispiel Makefiles - es ist üblicher als nicht, dass ein Projekt ein 'Makefile' hat, aber mit make können Sie auch mit '-f' ein anderes Makefile angeben.

Ich denke auch, dass die 1:1-Zuordnung zwischen Quellordner und Bild weniger nützlich ist, als Sie denken - ich habe festgestellt, dass es üblich ist, einen Build-Ordner zu generieren und daraus zu bauen, um die Menge der in den Kontext kopierten Daten zu behalten minimale und damit kleinere Bilder.

Sie sagen: "Meine Frage lautet also: riskieren wir nicht, viele Quell-Repositorys zu haben, die mit Docker build nicht wiederholbar erstellt werden können?"

Aber ich denke, dies ist bereits der Fall, einige Projektanforderungen bedeuten, dass eine einzige Möglichkeit zum Erstellen nicht praktikabel ist und die Dockerfile-Syntax nicht viel Konfigurierbarkeit zulässt (vom Design her und ich möchte nicht, dass sich das ändert) ...).

Ich mag auch den - einzigen Vorschlag nicht besonders. Ich denke, der Standard, den die Leute /wollen/ wenn sie bauen, ist, dass ein bestimmter Kontext erstellt wird, nicht alles - wenn ich Docker-Build ausführe, möchte ich /nur/ die Dockerfile ausführen. Aber ich möchte auch die Möglichkeit haben, ein anderes Image zu haben, das /kann/ gebaut werden kann.

Nach meinem Verständnis liegt das Problem hier darin, dass wenn
ein Dockerfile verkabeln (cat Dockerfile | docker build -) wir verlieren die Arbeit
Verzeichnis für ADD und CP.

Wird das Problem lösen, indem wir ein Flag für Docker-Build hinzufügen, das es uns ermöglicht,
angeben, wo sich der Inhalt des Quellordners befindet?

cat Dockerfile | docker build --cwd=~/my_docker_data_files -

In diesem Vorschlag gibt das Flag --cwd den Basisordner für ADD und CP an
Befehle.

2014-06-29 19:42 GMT+10:00 Peter Braden [email protected] :

du sagst "Meine Frage ist also: riskieren wir nicht, viele Quellen zu haben?
Repositorys, die mit docker build nicht wiederholbar erstellt werden können",

Aber ich denke, das ist bereits der Fall, einige Projektanforderungen bedeuten das
Eine einzige Möglichkeit zum Erstellen ist nicht praktikabel und die Dockerfile-Syntax nicht
ermöglichen eine Menge Konfigurierbarkeit (absichtlich und ich würde nicht wollen)
das zu ändern...).

Ich mag auch den - einzigen Vorschlag nicht besonders. Ich denke die Standardeinstellung
dass die Leute /wollen/ wenn sie bauen, dass ein bestimmter Kontext gebaut werden soll,
nicht alles - wenn ich docker build ausführe, möchte ich /nur/ die Dockerfile
ausgeführt werden. Aber ich möchte auch die Möglichkeit haben, ein anderes Bild zu haben, das /kann/ sein
gebaut.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/dotcloud/docker/issues/2112#issuecomment -47449994.

@llonchj tatsächlich https://github.com/dotcloud/docker/pull/5715 löst das (in gewisser Weise) und das ist bereits mit Master zusammengeführt.

@shykes ist definitiv offen für eine weitere Multi-Image-PR, obwohl ich mich nach einem Blick auf #5715 frage, ob dieser spezielle PR noch relevant ist.

Nach dem ursprünglichen Kommentar von

Wäre schön, wenn ich [command redacted] angeben könnte, damit ich Dateien HINZUFÜGEN und auch mehrere Dockerfiles haben könnte.

Pro @cap10morgan...

Ich denke, das, was ich wirklich gerne hätte, ist, die Konzepte "Build-Kontext" von "Dockerfile-Speicherort / -Name" trennen zu können.

Ist das nicht genau das, was #5715 tut? So wie ich es verstehe:

$ cd myapp
$ ls Dockerfile
Dockerfile
$ docker build -t gabrtv/myimage
Successfully built gabrtv/myimage
$ ls subfolder/Dockerfile
Dockerfile
$ tar -C subfolder -c . | docker build -t gabrtv/myotherimage -
Successfully built gabrtv/myotherimage

Ich weiß, dass dies keine Multi-Image-Builds aus dem Repo-Root löst (was ich zustimme, wäre schön), aber ich frage mich, ob diese spezielle PR/Implementierung jetzt mit #5715 zur Ruhe gebracht werden kann.

@gabrtv Es scheint mir, dass #5715 nicht den @shykes- Kriterien entspricht, einen einzigen Befehl zu haben, der immer funktioniert. tar -C subfolder -c . | docker build -t gabrtv/myotherimage - ist für mich extrem nicht offensichtlich.

Darüber hinaus erlegt es dem Entwickler lästige (wenn nicht sogar belastende) Einschränkungen in Bezug auf das Repository-Layout auf. Nicht unlösbar, aber "Oh, und ich muss das gesamte Repo neu organisieren" wird niemandem helfen, seinen Chef davon zu überzeugen, zu Docker zu wechseln.

Ich persönlich mag den neuesten Vorschlag von @shykes sehr , mit möglicherweise mehreren .dockerfile (warum nicht nur .docker?) Dateien, die alle standardmäßig erstellt werden. Dies macht es einfach, mit einem Befehl zu starten und später zu optimieren.

Je nach Implementierung könnte man den Build-Kontext dafür nur einmal über alle Images hochladen, was die Kosten für das Erstellen mehrerer Images reduzieren würde. Da ich keine .dockerignore habe, ist mein Build-Kontext mehrere hundert Megabyte groß und ich muss ziemlich lange warten, bis mein Kontext hochgeladen wird, also wäre das schön.

@rattrayalex glauben Sie mir, ich stimme dem Ziel zu, "einen einzigen Befehl zu haben, der immer funktioniert". Es besteht eine gute Chance, dass ich den Code schreibe und die PR einreiche. :zwinkern:

Mein Punkt ist, dass wir diese Diskussion vom Standpunkt der Projektorganisation aus an anderer Stelle führen sollten und nicht über ein langwieriges Thema mit dem Titel Allow specifying of a dockerfile as a path, not piping in :

  1. Der Großteil der Diskussion hier steht in keinem Zusammenhang mit @shykes neuem Vorschlag in https://github.com/dotcloud/docker/issues/2112#issuecomment -47448314
  2. Das ursprüngliche zugrunde liegende Problem (das Trennen des Build-Kontexts von Dockerfile) wird durch #5715 behoben, obwohl es vielleicht nicht jedermanns Geschmack ist

Ich zitiere @llonchj...

Nach meinem Verständnis liegt das Problem hier darin, dass wir beim Versenden einer Dockerfile (cat Dockerfile | docker build -) das Arbeitsverzeichnis für ADD und CP verlieren.

Mit anderen Worten, wenn Sie mit docker build -t <image> -f <path-to-dockerfile> einverstanden waren , können Sie tar -C <path-to-context> -c . | docker build -t <image> - als funktional äquivalente Problemumgehung verwenden, bis wir einen PR für @shykes- Vorschlag zusammenstellen können.

Ich schlage vor, dass wir dies schließen und woanders eine neue Diskussion starten (Mailingliste? neue Ausgabe?).

Danke an alle, die sich heute zu diesem Thema gemeldet haben:

@shykes danke für die Begründung. Ich denke, unser Grund für diesen Wunsch (andere Leute können sich einmischen) liegt in unserer Erfahrung: Jede Anwendung erfordert Out-of-Band-Informationen, um in einem ausgewählten Kontext ausgeführt zu werden. Alle unsere Anwendungen haben mehr als einen Kontext. Die Art und Weise, wie Docker-Build strukturiert war, zwang Anwendungsentwickler, das Wissen über diese Informationen in ihre Repository-Struktur zu verschieben oder benutzerdefinierte Build-Skripte zu erstellen, die das Verhalten von Docker-Builds, die die Informationen enthalten, überschreiben.

@gabrtv Ich denke, fast die gesamte Diskussion hier bezieht sich speziell auf dieses Thema und bin froh, dass es endlich hier diskutiert wird. Der Titel der Ausgabe und einige der "Entdeckungs"-Beiträge sind wahrscheinlich etwas irrelevant, daher ist eine neue Ausgabe oder eine PR mit einem sauberen Start, die auf diese verweisen, wahrscheinlich gut.

Der Vorschlag von @shykes Kommentar klingt für mich nach einer Lösung.

Wäre "Dockerfile.frontend-prod" nicht besser, damit alle Dockerfiles
in einem Verzeichnis natürlich zusammen sortieren?

Sorry, aber das ist einfach albern. Wenn mein Repository 100 Dienste erstellt, möchte ich sicherlich keine 100 Dockerfiles im Stammverzeichnis haben. (Beispiel: das dotCloud PAAS-Repository.)

Ich möchte auch kein einziges riesiges Dockerfile mit 100 Abschnitten.

Ich möchte 100 Dockerfiles, und ich möchte sie in separaten Verzeichnissen.

(Und nein, ich kann nicht einfach jeden Dienst in seinem eigenen Verzeichnis erstellen, da fast alle Dienste gemeinsamen Code und Bibliotheken verwenden, die _außerhalb_ des Verzeichnisses jedes Dienstes liegen.)

Auch hier verstehe ich nicht, warum es so eine große Sache ist, ein zusätzliches Flag zum Angeben des Pfads zur Dockerfile (standardmäßig nur Dockerfile ) zu haben?

Außerdem stimmt der aktuelle Vorschlag ( <imagename>.Dockerfile ) überhaupt nicht mit dem aktuellen Design von Automated Builds überein. Wenn ein Repository auf einem meiner Build-Systeme kompromittiert wird, könnte der Angreifer alle meine Repositorys überlasten...?

@jpetazzo Wie die meisten vernünftigen Menschen begrüße ich Meinungsverschiedenheiten, mag es aber nicht, als albern bezeichnet zu werden. Bitte bemühen Sie sich, Ihre Argumente zu präsentieren, ohne die Intelligenz Ihrer Kollegen zu beleidigen. Vielen Dank.

_Wieder verstehe ich nicht, warum ein zusätzliches Flag zum Angeben des Pfads zum Dockerfile (standardmäßig nur Dockerfile) so eine große Sache ist?_

Ich habe oben ein konkretes Argument vorgebracht. Lesen Sie es gerne und präsentieren Sie ein Gegenargument.

Re: Unordnung. @gabrtv hatte die gleichen Bedenken im IRC. Nach einigen Diskussionen haben wir diese Alternative gefunden:

$ ls Dockerfile Dockerfiles/*
Dockerfile
Dockerfiles/frontend-prod
Dockerfiles/frontend-dev

Gleiche Idee, aber weniger einzelne Dateien, die im Root-Repository herumliegen.

Außerdem ist der aktuelle Vorschlag (.Dockerfile) passt überhaupt nicht zum aktuellen Design von Automated Builds. Wenn ein Repository auf einem meiner Build-Systeme kompromittiert wird, könnte der Angreifer alle meine Repositorys überlasten...?

Wie heißen sie jetzt? Wenn Sie ein Repository mit dem Namen "abc" mit nur einer einfachen Dockerdatei haben, wäre es sinnvoll, ein von diesem generiertes Image mit dem Namen "abc" zu erstellen. Wenn Sie ein Repo "xyz" mit "Dockerfile.abc" und "Dockerfile.zzz" haben, ist es sinnvoll, Builds aus diesen als "xyz-abc" und "xyz-zzz" zu benennen.

Ich befinde mich in einer ähnlichen Situation wie Sie (viele Dienste, jeder in eigenen Unterordnern mit gemeinsamen Teilen) und die explizite Option, ein Dockerfile für die Build-Zeit festzulegen, würde mein Denken erleichtern, aber dann kann ich auch sehen wie ich den "Dockerfile.*"-Vorschlag mit dem bereits veröffentlichten "tar file as context" kombinieren kann, um das zu bekommen, was ich will - die Root-Dockerfiles für jeden Dienst würden ihre Build-Images generieren (mit Compilern und so) und wann diese ausgeführt werden, würden sie ein Kontext-Tar mit bereits kompilierten ausführbaren Dateien und eine Produktions-Dockerdatei (aus dem Dienstordner selbst) ausgeben, die ein Image mit nur den Laufzeitabhängigkeiten beschreiben würde.

Tatsächlich schreibe ich dies jetzt sogar mit einem einzigen Root-Dockerfile, weil meine Build-Umgebung für alle Dienste mehr oder weniger gleich ist und ich ihr zur Laufzeit einfach einen Parameter übergeben kann, um ihr mitzuteilen, welchen Service-Release-Kontext-Tar ich erstellen möchte.

@shykes nun , wenn wir so weit gekommen sind, Dockerfile/* zu haben, warum gehen Sie dann nicht einen Schritt weiter und lassen Sie "docker build" einfach nach Dateien mit dem Namen "Dockerfile.*" in allen Unterordnern des aktuellen Verzeichnisses rekursiv suchen und alle im Kontext des aktuellen Verzeichnisses ausführen? Und wenn wir schon bei if sind, bieten Sie eine Option an, um einfach einen von ihnen zu bauen ... wie "-f"? :)

... mag es nicht, albern genannt zu werden

Ich wusste nicht, dass "dumm" als beleidigend empfunden werden kann; Ich meinte vielleicht nur "ungeschickt" und entschuldige mich daher für den Missbrauch des Wortes.

Ich denke, Ihr spezifisches Argument war "Ich möchte nicht, dass die Leute Dockerfiles an zufälligen Orten ablegen und systematisch -f wenn dies nicht unbedingt erforderlich ist". Ist das richtig? In diesem Fall ist es sinnvoll, ein Dockerfile oben im Repository zu beauftragen und die anderen Dockerfiles aufzulisten. Wenn diese Datei nicht vorhanden ist, kann der Builder den Betrieb verweigern (oder eine Warnung ausgeben), und wenn nur eine Docker-Datei aufgeführt ist, kann der Builder auch eine Warnung ausgeben. Ich glaube nicht, dass die Parallele mit -v und -p hier angebracht ist.

@aigarius Wenn wir das ./Dockerfile.* und ./Dockerfiles/* besteht darin, dass sie einem einzigen Namespace zugeordnet sind, den wir verwenden können, um die resultierenden Bilder zu benennen. Im Gegensatz dazu, wenn ich ./foo/Dockerfile.db und ./bar/Dockerfile.db und ich docker build -t shykes/myapp . , welches wird dann shykes/myapp/db ?

welches wird shykes/myapp/db genannt?

Weder. In einem solchen Szenario würden Sie einen vollständigen Pfad zum Dockerfile in den Namen codieren, sodass Sie "shykes/myapp/bar/db" und "shykes/myapp/foo/db" haben. Das kommt dem Java-Namespace _nicht_ unangenehm nahe, aber ich überlasse es anderen, zu entscheiden, ob das gut oder schlecht ist.

@shykes : In Bezug auf Vagrant verwende ich und höchstwahrscheinlich einige andere Vagrant für einige überlappende Funktionen von Docker. Für mich muss ich also davon überzeugt sein, dass meine aktuellen Multi-Machine-Builds – die ich in Vagrant mit mehreren Maschinendefinitionen mache – bei der Verwendung von Dockerfiles nicht umständlicher werden. Die Sache ist, dass der "Kontext" in Vagrant viel flexibler ist, wo ich den Kontext von jedem Ort aus durch gemeinsame Verzeichnisse abrufen kann, ebenso wie die Sprache. Wenn ich also nur einen Dienst (oder eine Maschine) erstellen möchte Ich kann eine Umgebungsvariable setzen und sie "herumschweifen/bereitstellen". Ich verwende diese Methode täglich, um nur einige der Dienste in meinem System zu erstellen oder bereitzustellen. Und wenn mich ein wachsendes Vagrantfile zu sehr irritiert, kann ich leicht ein Sub-Vagrantfile "laden", das einen einzelnen Service oder Aspekt beschreibt.

Was die konkreten Vorschläge zum Umgang mit mehreren Dockerfiles betrifft, ja, das würde es uns ermöglichen, unsere Logik auf einzelne Dienste aufzuteilen. Groß. Aber ich möchte oder muss oft einen Dienst isoliert erstellen, also muss ich immer noch ein bestimmtes Dockerfile angeben ...

Meine Probleme hier sind also zweifach:

  1. Nicht für alle Dienste eine riesige unordentliche Datei erhalten
  2. In der Lage sein, einen bestimmten Dienst in dieser Datei/diesem Dateicluster zu erstellen

Auch hier ist Docker eine geniale Idee und ein geniales Tool, also WILL ich, dass Leute wie ich Vagrant für bestimmte Funktionen oder Anwendungsfälle aufgeben.

Es tut mir leid, wenn ich etwas wiederhole, das oben gründlich behandelt wurde, aber ich sehe nicht, wie eine Lösung besser ist, als eine Option '-f' zu unterstützen. Dh Modulo-Implementierungsprobleme aufgrund einer tief verwurzelten Abhängigkeit vom Dockerfile, das sich im Kontext-Root befindet, sehe ich darin keinen Nachteil.

Mit einer '-f'-Option könnte man die Unterverzeichnisse und Unter-Dockerfiles durchaus beliebig strukturieren, wie die Dockerfiles/-Ansätze oben. Ja, man bräuchte dann einen einfachen One-Line-Basher, um das genaue Verhalten nachzuahmen...

Es scheint eine Spannung zwischen Teilen und Flexibilität zu geben.

Wenn das Teilen die wichtigste Funktion ist, dann ja, eine Standard-Dockerdatei
macht Sinn.

Ich glaube nicht, dass das Teilen das wichtigste Feature ist. Teilen wird erreicht
über Bilder.

Außerdem verwenden wir Docker für Projekte, die explizit NICHT geteilt werden können. In
In diesen Fällen ist Flexibilität für uns viel wertvoller. Klingt wie viele in
die Gewinde alle befinden sich in derselben Position.

Die zweckgebundene Option -f gibt uns die Flexibilität, die wir brauchen. Auf der Kehrseite,
in der Lage zu sein, einen absoluten Pfad für den Build-Kontext anzugeben, wäre auch
Arbeit.
Am 3. Juli 2014, 18:00 Uhr, schrieb "David Bergman" [email protected] :

Tut mir leid, wenn ich etwas wiederhole, das oben gründlich behandelt wurde, aber ich sehe es nicht
wie jede Lösung besser ist, als eine '-f'-Option zu unterstützen. Dh, modulo
Implementierungsprobleme aufgrund einer tief verwurzelten Abhängigkeit von der
Dockerfile im Kontext-Root, sehe ich keinen Nachteil bei
es.

Mit einer '-f' Option könnte man die Unterverzeichnisse durchaus strukturieren
und Unter-Dockerfiles nach Belieben, wie die Dockerfiles/
Ansätze oben. Ja, dann bräuchte man einen einfachen One-Line-Basher, um
das genaue Verhalten nachahmen...


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/dotcloud/docker/issues/2112#issuecomment -47989616.

Stimmt zu, dass -f die größte Flexibilität mit minimaler "Überraschung" bietet (ich habe persönlich angenommen, dass es ein solches Flag gibt, und habe es ausprobiert, bevor ich zu diesem Thread gekommen bin).
Das Hinzufügen eines -c , entweder eines Verzeichnisses oder eines Tars, um auch den Kontext bereitzustellen, scheint ebenfalls eine großartige Ergänzung zu sein. Dies würde konstante cd s aus großen Build-Prozessen entfernen, zB; bei Unternehmen.

Außerdem klingt eine README-Datei, die Anweisungen für docker build -f foo/bar/Dockerfile -c foo/ einfach nicht so, als würde sie mich abschrecken.
Auch stimmte zu, dass docker build leicht nach Dockerfile s suchen könnte. Auf diese Weise ist ein Repo wie folgt aufgebaut:

-- README
-- foo/
---- Dockerfile
---- etc
-- bar/
---- Dockerfile
---- etc
---- subbar/
------ Dockerfile
-- context/
---- etc

würde alle möglichen Namenskonflikte vermeiden ( repo/bar/subbar ), die Menge leicht zu begründen sein und sollte in vielen Entwicklungskontexten Sinn machen. Es würde eine einfache Verwendung von sowohl docker build , was viele Kontexte aufbauen würde, als auch docker build -f , das in den meisten Kontexten das überflüssige Dockerfile weglassen könnte.

Wenn -f eine Datei und kein Docker-enthaltendes Verzeichnis ist, sollte das auch funktionieren, damit ein Entwickler eine Docker-Datei haben kann, die nicht erstellt wird, wenn docker build wird.

Damit das nicht verloren geht, hatte er gestern in der IRC-Diskussion mit @shykes eine andere Idee, dies umzusetzen:

  • Im Stammverzeichnis des Repositorys befindet sich ein Master-Dockerfile, das nur mehrere Zeilen in einem neuen Format wie "INCLUDE foo/bar/Dockerfile AS bar-foo" für jedes zu generierende Image enthält
  • Jedes Unterprojekt (wie das bar-Modul des foo-Unterprojekts), das ein separates Image benötigt, verwaltet eine reguläre Dockerfile unter foo/bar/Dockerfile. Pfade in diesem Dockerfile (für ADD und COPY) sind immer noch relativ zum Kontextstammverzeichnis, das das Stammverzeichnis des Repositorys ist (wo sich das Master-Dockerfile befindet).
  • Regelmäßiger Aufruf von "docker build -t mycorp/myapp ." erstellt alle im Root-Dockerfile registrierten Images und weist ihnen Namen wie "mycorp/myapp/bar-foo" in diesem Beispiel zu
  • Es müsste eine zusätzliche Befehlszeilenoption für "docker build" eingeführt werden, um nur einige der deklarierten Images zu erstellen, z. B. "docker build -t mycorp/myapp --only bar-foo,baz-db"

Nur für den Fall, dass die Leute immer noch nach einem Workaround suchen:

#!/bin/bash
ln -s Dockerfile-dev Dockerfile
docker build -t image/name-dev:latest .
rm Dockerfile

@shykes ping? Wenn es eine Genehmigung des Kernentwicklers für eine bestimmte Designlösung gibt, ist es viel wahrscheinlicher, dass jemand versucht, dies zu implementieren und einen Pull-Request zu stellen.

+1 zur Lösung -f, obwohl ich zustimme, dass jedes Repo theoretisch seinen eigenen Dienst bereitstellen sollte. Manche Leute haben nicht den Luxus dieser Lösung. Mein besonderes Problem ist, dass ich ein Koch-Repo mit mehreren Kochbüchern habe und in der Lage sein muss, viele Dienste zu erstellen. Aber ich muss in der Lage sein, Verzeichnisse oben hinzuzufügen. Daher ist es optimal, den Kontext im Stammverzeichnis zu behalten und auf eine Docker-Datei in einem Unterverzeichnis zu verweisen.

"-f" wird aus den bereits genannten Gründen wohl nicht implementiert.

Es ist zwingend erforderlich, dass ein Build von Host zu Host genau gleich funktioniert, und Dinge, die davon abhängen, dass der Host auf eine bestimmte Weise eingerichtet wird (dh Dockerfile an einem zufälligen Ort und Kontext an einem anderen Ort), bricht diesen Vertrag.

Ich denke #7115 ist wahrscheinlich die richtige Lösung dafür

Es gibt auch #7204, die auch zu einem Großteil des Anwendungsfalls dafür passen würde, denke ich.

Ich mag beide der beiden vorgeschlagenen Lösungen nicht, bei denen der Dockerfile Syntax hinzugefügt wird. Keiner von ihnen scheint einfach zu sein. #7115 scheint immer noch nicht den Anwendungsfall zu lösen, in dem ich mehrere Bildtypen aus einem einzigen Repository generieren wollte, wie ich es zum Beispiel in einem meiner Projekte mache, um ein 'Test'-Image zu generieren und ein "Prod"-Bild. #7204 scheint eine zu komplizierte Lösung zu sein, die ein anderes Problem löst. -f ermöglicht _Konfigurierbarkeit_ für einen Build, während diese beiden Lösungen _sub_builds_ adressieren.

Ich hätte gerne eine Erklärung zu "Es ist zwingend erforderlich, dass ein Build von Host zu Host genau gleich funktioniert". Ich verstehe nicht, warum dies ein so wichtiges Prinzip ist.

So wie es ist, verwende ich make , um die Docker-Umgebung als Problemumgehung für dieses ganze Problem zu generieren, das anscheinend bereits gegen Ihren Host-to-Host-Lauf nach demselben Imperativ verstößt.

Für mich scheint -f eine pragmatische Lösung zu sein, aber wenn es nicht akzeptabel ist, dann können wir uns vielleicht eine Lösung vorstellen, die nicht darin besteht, die Dockerdatei in eine vollwertige Programmiersyntax umzuwandeln.

Es ist zwingend erforderlich, dass ein Build von Host zu Host genau gleich funktioniert

Auch ich würde gerne mehr darüber erfahren, warum das so wichtig ist. Unser Team ist aktuell
gezwungen, den Build-Prozess zu skripten - genau das, was Sie vermeiden möchten.

Wenn ich ein Bild aus einer Registrierung herunterlade, funktioniert es einfach. Ich muss nicht
baue es. Ist das nicht eine Host-to-Host-Reproduzierbarkeit? Warum baut
müssen auch Host-to-Host wiederholbar sein?

Am Mo, 28.07.2014 um 10:43 Uhr, Peter Braden [email protected]
schrieb:

Ich mag beide der beiden vorgeschlagenen Lösungen nicht, die das Hinzufügen von Syntax zum
dockerfile. Keiner von ihnen scheint einfach zu sein. #7115
https://github.com/docker/docker/issues/7115 sieht immer noch nicht danach aus
würde den Anwendungsfall lösen, in dem ich mehrere Arten von Bildern generieren wollte
aus einem einzigen Repo, wie ich es zum Beispiel in einem meiner Projekte tue, um
Generieren Sie ein "Test"-Bild und ein "Prod"-Bild. #7204
https://github.com/docker/docker/pull/7204 scheint wie ein
zu komplizierte Lösung, die ein anderes Problem löst -f erlaubt
_Konfigurierbarkeit_ zu einem Build, während diese beiden Lösungen auf
_sub_builds_.

Ich hätte gerne eine Erklärung zu "Es ist zwingend erforderlich, dass ein Build funktioniert"
von Host zu Host genau gleich." Ich verstehe nicht, warum das so ein Schlüssel ist
Prinzip.

So wie es ist, verwende ich make, um die Docker-Umgebung als
Problemumgehung für dieses ganze Problem, das anscheinend bereits gegen Ihre verstößt
Host-to-Host-Lauf den gleichen Imperativ.

Für mich scheint -f eine pragmatische Lösung zu sein, aber wenn es nicht akzeptabel ist,
dann fällt uns vielleicht eine lösung ein, bei der es nicht darum geht, den
dockerfile in eine vollwertige Programmiersyntax.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/2112#issuecomment -50347483.

Soweit ich das verstanden habe, ist die Schlüsselidee, dass Sie ein Git-Repo ziehen können und wenn Sie dort eine Dockerfile sehen, können Sie "docker build -t mytag" ausführen. darin und erhalten Sie den vollständigen erwarteten Build. Der Schlüssel hier ist, dass es keine benutzerdefinierten Build-Anweisungen gibt, die Leute falsch machen oder nicht wissen.
Was ein Kompromiss sein könnte, ist eine Möglichkeit, mehrere Docker-Images in einem einzigen Kontext zu definieren, wobei standardmäßig alle mit vordefinierten Unter-Tags erstellt werden und Sie dann die Möglichkeit haben, nur eines der vielen möglichen Images zu erstellen.
Auf diese Weise wird die gemeinsame Build-Syntax beibehalten und gleichzeitig beides ermöglicht: 1) viele verschiedene Bilder aus einem Kontext generieren; 2) Wählen Sie nur eine davon mit einer "erweiterten" Option aus.
Die vorgeschlagene Syntax ist in meinem obigen Kommentar beschrieben - https://github.com/docker/docker/issues/2112#issuecomment -48015917

@algarius danke, ich denke, an dieser Stelle sollten wir einen neuen Designvorschlag für die _INCLUDE_-Syntax eröffnen. Beispiele für Designvorschläge finden Sie unter #6802 oder #6805.

Der Ablauf sieht so aus:

  • Designvorschlag einreichen
  • Designvorschlag besprechen
  • Ich stimme dem Designvorschlag zu
  • PR für Designvorschlag senden

Seien wir ehrlich, Builds sind jetzt nicht wirklich wiederholbar.

Wenn ich RUN apt-get update && apt-get install build-essentials ruby python whatever in meinem Dockerfile habe, dann bin ich bereits ausgeliefert
was auch immer in den Repos "neuesten" ist, wenn ich das Image erstelle. Wenn
DU baust das Image eine Woche später, du bekommst möglicherweise verschiedene Versionen von
Abhängigkeiten zu denen, die ich habe.

@codeaholics Aber das liegt an Ihnen, weil Sie keine Version

Vermutlich ein fairer Kommentar

@codeaholics Sie haben Recht, dass die Wiederholbarkeit von Builds nicht perfekt ist, obwohl es Optionen zur Steuerung gibt (wie das Anheften von Versionen) und wir mehr bereitstellen sollten. Aber zumindest hat der Build immer den gleichen _Einstiegspunkt_, was bedeutet, dass wir später eine bessere Wiederholbarkeit _einführen_ können. Sobald Ihr Build jedoch von einem Drittanbieter-Tool abhängt, das Docker selbst vorgeschaltet ist, gibt es kein Zurück: Die Wiederholbarkeit Ihres Builds ist im Grunde Null, und keine zukünftige Verbesserung von Docker kann dies beheben.

Dabei geht es nicht nur um Wiederholbarkeit. Wenn Ihr Build von einem bestimmten Satz von Argumenten abhängt, die von _docker build_ nicht erkannt werden können, ist Ihr benutzerdefiniertes Tool das einzige Build-Tool der Welt, das es erstellen kann: Sie können nicht mehr von den verschiedenen CI/CD-Tools und Plugins profitieren, die davon ausgehen ein nativer, auffindbarer _Docker-Build_.

@peterbraden in #7115, sobald Sie die Möglichkeit für mehrere PUBLISH Aufrufe hinzugefügt haben, können Sie jetzt mehrere Bilder erstellen. Dann können Sie die Konfigurierbarkeit hinzufügen, indem Sie die Auswahl der zu erstellenden Unterimages zulassen. Entscheidend ist, dass die Konfigurierbarkeit _innerhalb der von Docker auffindbaren Sub-Images_ stattfindet. So bewahren Sie die Auffindbarkeit.

@shykes > sobald Ihr Build von einem Drittanbieter-Tool abhängt, das Docker vorgeschaltet ist
selbst ... die Wiederholbarkeit Ihres Builds ist im Grunde Null.

Ich stimme zu. Ich denke, die meisten meiner Dockerfiles hängen von apt und den apt-Repositorys ab
ändern sich ständig. Ein Build ist heute nicht gleich einem Build
gestern. Ein gebautes Image ist der einzige Goldstandard imo.

Wenn die Wiederholbarkeit nicht der Hauptgrund für die Einschränkung ist, CI-Plugin
Support scheint ein ziemlich schwacher Fallback zu sein. Build-Tools wurden entwickelt, um
unterstützen idiosynkratische Anwendungsfälle. Ein Plugin, das nicht mehr kann als
Ein docker build cmd zu konfigurieren scheint ziemlich nutzlos zu sein. Mein Build-Tool ist
bereits eine Skriptumgebung. Schlimmer noch, das ganze Potenzial schaufeln
Use-Cases in die Dockerfile-Überstunden scheinen ein schlechter Weg für Architekten zu sein
es. Das Dockerfile sollte sich darauf konzentrieren, einfach ein neues Image zu erstellen, indem
Hinzufügen von Ebenen zu einem Basisbild. Andere Arbeiten scheinen außerhalb der Band zu liegen.

Ich liebe Docker bisher. Tolle Arbeit Jungs! Dieses spezielle Problem passiert einfach
ein Schmerzpunkt sein.

Am Mo, 28.07.2014 um 12:25 Uhr, Solomon Hykes [email protected]
schrieb:

@peterbraden https://github.com/peterbraden in #7115
https://github.com/docker/docker/issues/7115 , sobald Sie die Fähigkeit hinzugefügt haben
für mehrere PUBLISH-Aufrufe können Sie jetzt mehrere Bilder erstellen. Dann Sie
kann die Konfigurierbarkeit erhöhen, indem die Auswahl der zu erstellenden Unterimages ermöglicht wird.
Entscheidend ist, dass die Konfigurierbarkeit _innerhalb der Menge von
Sub-Images, die von Docker_ gefunden werden können. So bewahren Sie die Auffindbarkeit.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/2112#issuecomment -50361586.

@thedeeno Das Ziel des Dockerfiles besteht darin, anzugeben, wie ein Quellcode-Repository in etwas umgewandelt wird, das von Docker ausgeführt werden kann.

Wie wäre es mit "das Ziel von _a_ Dockerfile ist, anzugeben, wie ein Quellcode-Repository in etwas umgewandelt wird, das Docker ausführen kann."

Ich denke, wir können uns einig sein, dass es eine Möglichkeit gibt, mehrere Repo->Image-Mappings zu haben. Viele von uns missbrauchen dafür Shell-Skripte und Makefiles. Nach meiner Erfahrung habe ich nicht viele benutzerdefinierte Makefiles gesehen - Konfiguration und Standardeinstellungen sind eine starke Kraft. Aus diesem Grund bin ich nicht davon überzeugt, dass Menschen, die die Konventionen missbrauchen, ein realistisches Szenario sind.

Die von Ihnen vorgeschlagene Alternative, ein Schlüsselwort zur Dockerfile-Syntax hinzuzufügen, macht das Erstellen von Dockerfiles komplexer. Ich bin dafür, diese Syntax so einfach wie möglich zu halten. PUBLISH et al. erscheinen im Vergleich zum Rest der Dockerfile-Syntax unelegant.

Es gibt auch die Idee, bestehenden Werkzeugkonventionen zu folgen. Wie bereits erwähnt, ist -f ein so häufiges Muster, dass die Leute es ausprobieren, ohne zu wissen, dass es funktioniert. Eine Benutzeroberfläche sollte intuitiv sein und die Leute _get_ -f Flags. Das Erforschen der neuen Dockerfile-Syntax ist nicht annähernd so intuitiv.

@peterbraden @shykes Ich stimme zu, dass -f einfacher und intuitiver ist. Ich habe dieses Problem ursprünglich gefunden, weil ich _erwartet__, dass Docker diese Funktion bereits hat und danach gesucht habe (vermutlich, als es standardmäßig nicht funktionierte) am ersten Tag, an dem ich damit begann, es für unsere Anwendungen zu testen.

Dies ist kein Grenzfall, es sei denn, Sie befinden sich in einer Situation, in der Sie Ihre Software nicht testen oder Ihre Software nicht in mehreren Umgebungen ausführen. Jedes Repo, das ich in den letzten 10 Jahren berührt habe, muss in verschiedenen Kontexten ausgeführt werden können. Ich denke, viele Leute in diesem Thread haben das gleiche Problem. Wir sind uns alle einig (glaube ich), dass Konventionen für den Standardkontext für Ihre Anwendung offensichtlich wertvoll sind (vorausgesetzt, Sie haben eine).

Ich habe #7115 (schnell) durchgelesen und verstehe nicht, wie es dieses Problem für uns löst. Vielleicht ist dies ein Problem der Dokumentation zum PR, aber wenn es schwer zu kommunizieren ist, wird es IMO zu Frustration und Fehlern führen, während -f or ein ähnliches Flag würde wenig Aufwand erfordern, um es richtig zu erklären und zu verwenden.

Erstellt einen neuen Vorschlag mit dieser INCLUDE-Idee - https://github.com/docker/docker/issues/7277

Als Randnotiz - es könnte sich lohnen, über einen effizienteren "APT"-Befehl nachzudenken, anstatt über das klobige "RUN apt-get install -y ..." (und dann anschließend YUM, EMERGE, PACMAN und was auch immer)

Oh, und wenn man bedenkt, dass viele Leute sowieso nur die Option "-f" ausprobieren, wäre es nett, wenn Sie jedes Mal, wenn Sie versuchen, sie zu verwenden, eine nette Fehlermeldung erhalten, die Sie zu einer Seite in der Dokumentation führt, die die neue Lösung beschreibt.

Ich glaube wirklich, dass wir alle den Elefanten im Raum ignorieren.

@shykes sagt Dinge wie "Die Tatsache, dass Sie auf ein Quellcodeverzeichnis ohne weitere Informationen außerhalb des Bandes zeigen und daraus ein Image genau nach den Spezifikationen des Upstream-Entwicklers erstellen können, ist sehr mächtig und a wichtiges Unterscheidungsmerkmal von Docker."

Ich bin mir ziemlich sicher, dass dies gleichbedeutend mit der Aussage ist " docker build . in ein Verzeichnis einzugeben sollte absolut immer das Richtige tun", was gleichbedeutend mit der Aussage "Wenn Sie ein Projekt haben, für das es nicht offensichtlich das Richtige gibt" docker build . zu tun, du liegst falsch"

Ich kann nicht für die Beweggründe anderer Leute sprechen, die diese Ausgabe abonniert haben, aber meine eigenen Beweggründe für diese Ausgabe sind genau die Fälle, in denen docker build . kein offensichtliches Verhalten zeigt. Wollte ich eine Debug-Version oder eine Release-Version? Wollte ich Postgres einbacken oder sollte ich separate App- und Postgres-Bilder ausgeben? Wollte ich, dass es mit Testdaten oder Produktionsdaten geladen wird? Wollte ich die Tests durchführen?

Klar, ich würde gerne in einer Welt leben, in der die Leute diese Fragen nicht beantworten müssen, um einen Build zu bekommen. Aber ich lebe nicht in dieser Welt. Natürlich könnte ich willkürlich einige Antworten auf diese Fragen auswählen und ein Verhalten für docker build . . Aber Tatsache ist, dass etwas Willkürliches zu bauen, wenn der Benutzer docker build . eingibt, nicht "das Richtige tut".

Die Realität der Situation ist, dass es Projekte gibt, bei denen es nicht offensichtlich das Richtige zu bauen gibt. Es gibt viele Möglichkeiten, dies im Docker zu lösen, z. B. Unterstützung von -f oder die Auswahl aus einer Liste von Zielen, die von woanders importiert wurden, oder verschiedene andere Vorschläge. Aber sie haben alle die Eigenschaft, dass docker build . kaputt geht. Hier gibt es eine grundlegende Impedanzfehlanpassung, Sie können nicht einfach einen Ausweg vorschlagen.

Die Vorstellung, dass jedes Projekt etwas Sinnvolles für docker build . auswählen kann, ist eine Fantasie. Projekte, die unmöglich etwas Sinnvolles tun können, gibt es, und zwar zahlreich. Die einzige Frage an dieser Stelle ist, ob Docker den Multi-Build-Produktcharakter dieser Projekte direkt unterstützen wird oder ob sie auf traditionelle Buildtools wie make oder sogar Shell-Skripte zurückgreifen. Dies geschieht jetzt : zum Beispiel verwendet Discourse, eines der größeren Distributed-on-Docker-Projekte, zum Teil ein selbstgebautes Build-System, um dieses Problem zu lösen.

@drewcrawford Sie sehen, genau das ist das Problem. "Docker bauen." sollte _das_ Bild erstellen. Das einzig wahre Bild. Sie sollen die Docker-Ausführungsparameter ändern, um das Verhalten des einzigen Images an verschiedene Umgebungen anzupassen.
In diesem Zusammenhang möchten Sie wahrscheinlich eine Release-Version, nur die App, sonst nichts. Alle anderen Dinge, wie "das Postgres-Image", sind verschiedene Dinge, die zur Laufzeit mit Ihrer App verknüpft werden. Sie können dasselbe Release-Image nehmen und mit einem nicht standardmäßigen Befehl ausführen, um Ihre Tests darin auszuführen.
Im Idealfall müssen Sie mit Multiimage-Unterstützung nicht einmal zwischen "Release", "Debug" und "mit Tests" Builds wählen - Sie haben nur alle mit einem Basis-Build und 3 kleinen Unterschieds-Builds obendrauf.
Wenn Sie versuchen, Docker auf die alte Denkweise zu verbiegen, werden Sie eine schlechte Zeit haben. Versuchen Sie nicht, eine Schraube mit einem Schraubendreher zu hämmern.

@algarius Ich denke, das Problem ist, dass dieses Denken nicht für reale Anwendungen gilt, und niemand hat erklärt, wie es funktioniert, wenn wir hier wirklich einen Paradigmenwechsel haben sollen.

Das Zulassen mehrerer Images ist der einfachste und intuitivste Weg, um die Anforderungen zu erfüllen, die die meisten realen netzwerkzugänglichen Anwendungen haben (mehrere Umgebungen mit unterschiedlichen Abhängigkeiten). Ist es wünschenswert, die Grammatik auf eine Weise zu verkomplizieren, die nicht kommuniziert werden kann, um dies zu lösen? Am Ende überarbeiten und verschleiern Sie nur die Tatsache, dass Sie > 1 Umgebung mit unterschiedlichen Abhängigkeiten haben, die leicht auf einfache Weise wie mehrere Dockerfiles ausgedrückt werden können, die für Endbenutzer der Software fast keine Erklärung benötigen.

@drewcrawford lieferte ein konkretes Beispiel dafür, wie dies in einer aktuellen, in der gehandhabt wird, die mit Docker-Unterstützung vertrieben wird. Wie sollten sie das tun?

@aigarius Es ist nicht so, dass ich "den Docker-Weg" nicht verstehe. Ich finde es einfach falsch.

Zum Beispiel benötigen die Tests möglicherweise einen anderen Build – ein ehrliches _recompile_ –, da bestimmter Protokollcode, der für die Produktion zu langsam ist, bedingt einkompiliert werden muss.

Wenn dies nach einem Job für ein Make-System klingt, haben Sie Recht - und das ist es tatsächlich, was Leute wie ich tun, sie finden Wege, Docker-Builds mit tatsächlichen Build-Systemen zu skripten.

Das Problem dabei ist, dass ein Dockerfile nicht sowohl die bevorzugte Benutzeroberfläche zum Bauen sein kann als auch wesentlich weniger leistungsfähig als zB make . Es kann entweder die bevorzugte Benutzeroberfläche zum Erstellen mit Makelike-Power sein oder es kann ein Low-Level-Tool mit make usw. als echte Benutzeroberfläche sein. Aber "echte" Build-Systeme sind nicht beliebig kompliziert - sie sind kompliziert, weil die Leute die Funktionen nutzen, und daran werden auch noch so viele vereinfachte Docker-Builds nichts ändern. Alles, was passieren wird, ist, dass docker das neue cc , das die Leute mit make aufrufen.

@shykes @drewcrawford @aigarius Ich habe einen Vorschlag für eine einfache Option -f auf die gleiche Weise geschrieben, wie @shykes zuvor in diesem Thread hier beschrieben hat: #7284

@drewcrawford Sie haben Recht, um die bevorzugte Benutzeroberfläche für Build zu sein, muss docker build mindestens so leistungsstark sein wie zB. make . Dazu gibt es 2 Möglichkeiten:

  • 1) Wir könnten versuchen, jedes Feature jeder Variation von make neu zu implementieren, sowie jede Alternative, die es gibt: Maven, Scons, Rake und natürlich die guten alten Shell-Skripte.

ODER

  • 2) Wir konnten erkennen, dass diese Build-Tools selbst ausführbare Programme sind, das heißt, sie haben Laufzeitabhängigkeiten und wurden selbst aus Build-Abhängigkeiten gebaut - und so weiter bis hinunter. Und wir könnten Ihnen eine Möglichkeit bieten, Ihr bevorzugtes Build-Tool _tatsächlich zu verwenden_. Wir müssten also make nicht neu implementieren, da wir tatsächlich make erstellen und ausführen können.

Wenn Sie make sagen, auf welche Marke beziehen Sie sich? Welche Version? Von welchem ​​SVN-Checkout genau gebaut? Mit welchen Build-Optionen? Mit welcher libc ist es verlinkt? Dieselbe Frage für cc die Sie auch erwähnen. Vielleicht spielt es keine Rolle - vielleicht wird Ihre App genau gleich, unabhängig davon, welche zufällige Version von make ich letztendlich verwende, um sie zu erstellen. Aber vielleicht spielt es auch eine Rolle. Vielleicht ist die einzige Möglichkeit für mich, genau den gleichen Build wie Sie zu erhalten, darin, genau den gleichen Build von Make und Cc zu verwenden, als Sie verwendet haben. Und das geht heute nicht einfach - aber das möchte ich gerne tun.

Ich halte docker build nicht wirklich für ein Build-Tool, sondern eher für ein Meta-Build-Tool: einen bekannten Ausgangspunkt, von dem aus Sie jede Build-Umgebung zuverlässig wiederherstellen können. Das ist die Motivation für #7115.

@shykes Ich denke nicht, dass es notwendig ist, wirklich _jedes_ Feature von make, Maven, Rake usw. zu replizieren. Schließlich replizieren diese Tools nicht jedes Feature voneinander, und irgendwie kommen sie miteinander aus.

Es ist jedoch erforderlich (wenn Docker die bevorzugte Benutzeroberfläche zum Erstellen von Images sein soll), dass das Dockerfile eine ausdrucksvollere Sprache wird, als es derzeit ist.

Der Vorschlag in dieser Ausgabe ist wirklich ein bescheidener Schritt in diese Richtung: Er sagt: "Wir brauchen ein Äquivalent zu den _Zielen_" von uns. Die Frage "welche Version von make" kommt nicht wirklich ins Bild - das Konzept eines "Targets" ist bei Make, Maven, Rake und jedem anderen ernsthaften Build-System üblich. Sie haben eine unterschiedliche Syntax, aber die Tatsache, dass die Funktion selbst universell ist, sollte ein Hinweis darauf sein, dass dies eine Sache ist, die Leute häufig tun, wenn sie Dinge bauen.

Es spielt keine Rolle, ob es sich bei dem, was sie erstellen, um ein C-Programm, ein Docker-Image oder irgendetwas dazwischen handelt – Sie erstellen immer noch ein Ziel. Die Idee eines Build-Targets ist so grundlegend, dass es Build-Systemimplementierungen, Programmiersprachen und Betriebssysteme umfasst. Wir sprechen hier nicht über die Replikation irgendeines obskuren GNU Make-spezifischen Features, wir sprechen über etwas, das die größtmögliche Übereinstimmung hat.

Sie versuchen hier ein Konzept eines "Meta-Build-Tools" einzuführen, aber so etwas gibt es nicht. So wie Docker Make-Builds orchestrieren kann, kann auch Docker-Builds orchestrieren, und tatsächlich wird make derzeit genau auf diese Weise verwendet, da es keine Möglichkeit gibt, Docker ein Build-Ziel anzugeben. Aber auf jeden Fall ist kein System von Natur aus mehr oder weniger Meta als das andere, es sind alles nur Build-Systeme, die Ziele bauen, aber im Fall von Docker ist nur eines erlaubt, und das ist das Problem.

Vorschläge wie #7115 sind interessant, aber wenn ich nichts übersehe, sind sie kein effektiver Ersatz für Ziele. Ein Ziel sagt dir, was du bauen sollst. #7115 gibt Ihnen ein flexibleres DSL, das immer noch nur eines aufbauen kann. Das ist etwas, aber es ist nicht das, was hier verlangt wird.

docker build -t my_project_builder .
# Builds the builder container
docker run my_project_builder my_target | docker build -t my_project/my_target -< Dockerfile_MyTarget
# target is built, tarballed, and sent to stdout, then piped into a new docker build as the context and custom Dockerfile name

@drewcrawford nur um zu bestätigen, ob Docker etwas Äquivalentes zu Make-Zielen erlaubt, damit Sie 1) angeben können, welches Ziel erstellt werden soll, z. make clean; make foo , 2) standardmäßig _alle_ Ziele erstellen und 3) eine Möglichkeit haben, Ziele aufzuzählen... Das wäre für Sie zufriedenstellend?

Das wäre zufriedenstellend... Ich würde es vorziehen, standardmäßig ein vom Entwickler ausgewähltes Ziel zu verwenden, anstatt standardmäßig alle Ziele zu verwenden, aber ich würde beide Lösungen akzeptieren

Das ist in Ordnung.

@shykes @drewcrawford :+1:

Alles, was passieren wird, ist, dass Docker das neue CC wird, das die Leute mit make aufrufen.

Der Vorschlag in dieser Ausgabe ist wirklich ein bescheidener Schritt in diese Richtung: Er sagt: "Wir brauchen ein Äquivalent zu den Zielen". Die Frage "welche Version von make" kommt nicht wirklich ins Bild - das Konzept eines "Targets" ist bei Make, Maven, Rake und jedem anderen ernsthaften Build-System üblich. Sie haben eine unterschiedliche Syntax, aber die Tatsache, dass die Funktion selbst universell ist, sollte ein Hinweis darauf sein, dass dies eine Sache ist, die Leute häufig tun, wenn sie Dinge bauen.

@drewcrawford :+1: +1.000.000

Hier ist die Situation, in die ich immer wieder stoße:

Ich möchte zwei Docker-Container aus meinem Repository erstellen. Vielleicht ist einer der Server, einer die Datenbank. Oder vielleicht ist einer der Server und der andere ein Client, der über API-Aufrufe automatisierte Tests gegen den Server durchführt.

Auf jeden Fall gibt es einige Dateien im Repo, die ich für diese beiden Container HINZUFÜGEN muss. So wie es ist, ist dies unmöglich, ohne die separaten Dockerfiles einzeln in ein Bash-Skript zu kopieren, den Build durchzuführen und dann das Dockerfile zu ersetzen oder zu löschen.

Ich brauche entweder:

  1. Der Befehl -f zur Angabe der Datei, die als Dockerfile verwendet werden soll.
  2. Die Möglichkeit, eine Datei hinzuzufügen, die nicht im Down-Pfad der Dockerfile ist.

Da immer wieder gesagt wurde, Nummer eins sei ein No-Go, und ich nehme an, Nummer zwei ist technisch noch schwieriger, wie geht das "richtig"?

@ShawnMilo

@shykes letzter Kommentar schien darauf hinzudeuten, dass dies nicht mehr so ​​anstößig ist wie früher, aber ich denke, wir sind immer noch unklar, welcher vorhandene Vorschlag angemessen wäre oder was geändert werden müsste, wenn dies nicht der Fall ist.

@jakehow Danke für das Update. Eine offizielle Lösung des Problems scheint also noch in weiter Ferne zu liegen. Gibt es in der Zwischenzeit einen "guten Weg", dies zu tun? Die beste Idee, die ich habe, ist ein Bash-Skript, das die Dateien einzeln in "Dockerfile" im Repository-Stamm kopiert und die Images erstellt. Es wird funktionieren, aber es fühlt sich schmutzig an.

@ShawnMilo ja, ich denke, die meisten Leute verwenden dafür ein Build-Tool (make, Rake usw.) oder einfach nur altes Bash-Skript.

Oben hat jemand einen Ausschnitt gezeigt, in dem er ein Builder-Image hat, das sich auch damit befasst.

Hier ist mein Weg, mit diesem Problem umzugehen. Ich muss ein Image für verschiedene Versionen einer Plattform erstellen, sagen wir v2 und v3. Also habe ich eine Dockerfile.v2 und eine Dockerfile.v3 Wenn ich einen Build erstellen möchte, führe ich zuerst ln -s ./Dockerfile.v3 ./Dockerfile dann docker build . Eigentlich habe ich ein Skript und ich führe nur ./build v3 oder ./build v2

Während ich derzeit ein Skript verwende, das ein angegebenes Dockerfile mit ./Dockerfile verknüpft, wäre dies eine nette Funktion.

Ich habe eine PR #7995 erstellt, um zu versuchen, dies anzugehen. Einige der Lösungen, die in diesem (langen :-) ) Thread diskutiert werden, scheinen für die Leute furchtbar schmerzhaft zu sein. Eines der größten Verkaufsargumente von Docker (für mich) war, wie einfach es zu bedienen ist. Daher fühlt es sich nicht richtig an, die Leute zu bitten, durch diese Art von Reifen zu springen, um eine ziemlich einfache Frage zu stellen.

Es ist möglich, dass ich etwas übersehe, aber gibt es einen technischen Grund, warum es "Dockerfile" heißen muss? Beim Erstellen der PR konnte ich keine finden und war angenehm überrascht, wie einfach es zu ändern war.

@duglin, du hast meine ganze Unterstützung.

Dies ist, was wir tun, um das Fehlen einer -f Option in unserem aktuellen Projekt zu umgehen.

# build.sh
...
mv specialDockerfile Dockerfile
docker build -t $(PROJECT) .

Betrachten Sie dies als +1 zum Hinzufügen von -f .

Momentan kümmere ich mich auch um Dinge wie Kikito. Ich habe ein paar Shell-Skripte geschrieben, um verschiedene Images aus demselben Kontext zu erstellen, würde aber gerne eine Möglichkeit sehen, eine Docker-Datei aus dem CLI-Argument anzugeben, wie bereits vorgeschlagen. +1 für diese Anfrage.

+1000

Ich bin heute darauf gestoßen, als ich versuchte, mit Docker ein plattformübergreifendes Golang-Projekt zu erstellen. Dies funktioniert, siehe boot2docker , aber ich brauche ein Makefile, um das Innere und Äußere des Docker-Build-Prozesses zusammenzufügen, zB docker cp die Artefakte aus dem Docker in mein Build-Verzeichnis.

Wenn ich jedoch versuche, dies in einem Unterverzeichnis meines Repositorys zu verwenden, wird mein GOPATH beschädigt, da der .git-Ordner im Repository-Root fehlt. Ich muss ADD das Repo-Root erstellen und dann in meinem Unterverzeichnis erstellen, aber dies wird von Docker nicht zugelassen.

Nachdem ich diesen langen Thread gelesen hatte, sah ich Bedenken, dass Builds nicht reproduziert werden können. Eine Möglichkeit, dies zu mildern, besteht darin, der Option -f nur zu erlauben, innerhalb des Build-Kontexts oder nach unten zu zeigen. Auf diese Weise können Sie mehrere Dockerfiles in Unterverzeichnissen haben und diese aus dem Repository-Root erstellen. Zusätzlich können Sie dies auf Repo-Grenzen beschränken, zB auf der gleichen Ebene wie .git/.hg/.foo und darunter, aber nicht außerhalb des Repo.

Hier ist was ich denke

FROM scratch
BUILD myname1 path/to/dockerfile/in/context
BUILD myname2 path/to/dockerfile2/in/context
docker build -t myimage .

Dies würde 3 Bilder erzeugen:

  1. Hauptbild namens "myimage", das zum Beispiel nicht wirklich etwas enthält
  2. Ein Bild namens myimage-myname1
  3. Ein Bild namens myimage-myname2

Das Schlüsselwort BUILD würde einen Namen und einen Pfad zu einer Dockerfile annehmen. Dieses Dockerfile muss sich im ursprünglichen Kontext befinden.
Jeder Build-Befehl hätte Zugriff auf den vollständigen Kontext des Haupt-Builds.
Es kann sich jedoch lohnen, den Kontext auf den Verzeichnisbaum zu beschränken, in dem das Dockerfile enthalten ist.

-1

Sie könnten für diesen speziellen Fall einen Kontext-Feeder für docker build - wie Dockerfeed verwenden .

@itsafire Der Punkt ist, diese Art von Funktionalität in Docker zu integrieren, damit dies eine unterstützte Möglichkeit zum Erstellen Ihres Projekts sein kann. Ich bin sicher, die Leute würden es lieben, wenn dies auch mit automatisierten Builds funktioniert.

Ich bin hier ratlos. Wir haben mehrere Pull-Requests für diese zusätzliche Funktion, oder? Und es sieht nicht allzu schwer aus ... Man könnte sogar die von durchsetzen : den Pfad so zu beschränken, dass er relativ zum Kontext/Root ist. Das würde es zumindest mit boot2docket und dergleichen reibungsloser machen und es "portabel" machen.

Dies ist bei weitem die irritierendste Lücke in Docker, und da immer mehr Tools Docker als Teil seiner Funktionalität verwenden, ist es wichtig, dass wir schnell die Fähigkeit für ein '-f'-Flag hinzufügen, damit diese Tools darauf vorbereitet sind das, bevor es zu endgültig wird ... Verwandte: Ein Dockerfile mit mehreren Images reicht nicht aus, da diese verwandten "Meta"-Tools oft _ein_ Image pro Dockerfile annehmen! Auch die Verwendung von '-' bringt es mit diesen Werkzeugen nicht und schränkt die Funktionalität stark ein, wie wir alle wissen.

Kann jemand mit Autorität erklären, warum dieser Fix noch nicht zusammengeführt wurde oder zumindest warum diese schmerzlich fehlende Funktion immer noch nicht vorhanden ist?

Fängt an, sich wie Twilight Zone zu fühlen.

Ich vermute, es besteht ein Missverhältnis darin, wie das Docker-Team Docker verwendet / möchte, dass Docker verwendet wird und wie ein großer Teil der Community Docker verwendet. Korrigiere mich, wenn ich falsch liege.

Das Docker-Team möchte ein Software-Repository aufbauen, das dem Repository des Debian-Projekts nicht sehr ähnlich ist. Wo die Leute ihre Lieblingssoftware bekommen und sie einfach ausführen können. Der Build-Prozess für die Software sollte wiederholbar und offensichtlich sein.

Andere wollen ihr bestehendes Inhouse-Software-Deployment automatisieren, das mit vielen Build-Tools, CI-System etc. schon sehr komplex sein kann. Für sie ist Docker nur ein weiteres Tool, das in ihre Infrastruktur passen muss. Und sie brauchen etwas mehr Flexibilität bei der Verwendung von Docker.

Ich denke, Docker (wie .deb) kann die Bedürfnisse beider Parteien befriedigen, aber Kompromisse müssen eingegangen werden.

Das Grundproblem ist: Wo hört das auf? Turing-Vollständigkeit für Dockerfile ? Wahrscheinlich nicht. Es wird immer mehr Flexibilität geben, um einen speziellen Fall zu lösen. Einige Ideen werden in die Dockerfile-Sprache übernommen, andere nicht. Da Docker in der Lage ist, einen Kontext über stdin auf einem Build zu essen, können fehlende Funktionen über einen Präprozessor implementiert werden.

@itsafire Das letzte Mal, als ich nachgesehen habe, kann Docker ein Dockerfile essen, aber keinen Kontext. Tatsächlich wird der Kontext ignoriert, wenn Sie auf diese Weise ein Dockerfile bereitstellen. Wenn sie Unterstützung für das hinzufügen, was Sie vorgeschlagen haben, wäre dies ein geschlossenes Problem.

Ich habe eine Weile nicht nachgesehen, aber die grundlegende Anforderung lautet: Geben Sie uns eine explizite Möglichkeit, während des Builds sowohl ein Dockerfile ein context bereitzustellen. Ehrlich schockiert ist dies wie 8 Monate später und immer noch offen.

@thedeeno das ist tatsächlich möglich
cat mystuff.tar.gz | docker build -

@ cpuguy83, aber ich kann mit diesem Befehl kein explizites Dockerfile bereitstellen. Rechts?

@thedeeno ja, Sie tarnen jede beliebige Dockerfile mit dem gewünschten Kontext.

@cpuguy83 @thedeeno Nein, das funktioniert nicht, weil man dann keine Dateien HINZUFÜGEN kann, da sich keine im "cwd"-Bereich befinden, den man normalerweise mit einem Dockerfile bekommt.

Bearbeiten: Diese Aussage ist falsch; Ich habe das Beispiel von verstanden .

@ShawnMilo ja, das ist es. Alles im tar ist im Kontext.

@ cpuguy83 Entschuldigung, mein Fehler. Ich habe es hastig gelesen, weil es nur das Dockerfile einfügt, nicht ein ganzer Tarball.

@cpuguy83 Schön! Ich stimme dann ab, wenn es so funktioniert, wie Sie es vorschlagen.

Nebenfrage, in meiner benutzerdefinierten Lösung haben Zeitstempel den Cache beim Tarieren geknackt. Das ist immer noch ein Thema? Wenn ich denselben Ordner mehrmals tariere, wird der Cache beim Build verwendet?

Mach weiter so mit der tollen Arbeit!

Einen ganzen Kontext zu überführen erleichtert das, worüber wir oben gesprochen haben, überhaupt nicht.

Was wir wollen und brauchen, ist eine Möglichkeit, den _gleichen_ Kontext mit verschiedenen Dockerfiles zu verwenden. Wie die oben erwähnten "Build with Logging" und "Build without Logging" als einzelne Bilder. Ich habe viele andere Anwendungsfälle, in denen dies erforderlich ist.

Ich kann nicht sehen, wie das Tar-Ballen eines Verzeichnisses dabei helfen würde. Ja, man könnte ein spezielles Verzeichnis erstellen und das spezifische Dockerfile dorthin kopieren und dann das gesamte Kontextverzeichnis oder tar und ein neues Dockerfile anhängen und dann gzipping. Aber wie ist das einfacher als die [ziemlich schreckliche] Problemumgehung, die wir derzeit anwenden müssen, indem ein Präprozessorskript das richtige Dockerfile anlegt, bevor Docker ausgeführt wird?

Und das wird bei der Docker-Ökologie nicht helfen, wie ich oben erwähnt habe.

Habe ich etwas verpasst?

Wieder eine einfache '-f'-Option. Bitte. Bitte, bitte schön. Erzwingen Sie, dass es ein relativer Pfad des Kontexts ist. Das ist gut.

@davber Was Sie wirklich möchten, ist, dass Docker den Kontext und die Dockerfile-Datei für Sie übernimmt.
Und ich bin nicht ganz dagegen. Obwohl ich denke, dass verschachtelte Builds eine bessere Lösung dafür sein können.

@ cpuguy83 : Ja, also möchte ich, dass Docker das für mich

Verschachtelte Builds lösen nicht die Probleme, mit denen wir konfrontiert sind und die diesen Thread gestartet haben, und halten ihn am Laufen.

Das heißt, wir wollen immer noch den gleichen Root-Kontext verwenden.

Ja, wir können Dateien kopieren, und ja, um diese für uns seltsame Kopplung des Kontexts mit einer genauen Dockerfile namens 'Dockerfile' zu umgehen. Aber das ist nicht ideal, und das Einrichten von rsync, um sicherzustellen, dass die Dateien tatsächlich mit den Originaldateien identisch sind, ist einfach seltsam.

@ cpuguy83 :

@davber
Meine Meinung dazu ist folgende:

FROM scratch
BUILD myname1 path/to/dockerfile
BUILD myname2 path/to/another/dockerfile

Und das:

docker build -t myimage .

Würde 3 Bilder ergeben, "myimage", "myimage-myname1", "myimage-myname2".
Jeder innere Build hätte Zugriff auf den vollständigen Build-Kontext als absolute Pfade. Relative Pfade wären relativ zur Dockerfile.
Und das "myimage" könnte auch seine eigenen Sachen haben, die über nur BUILD-Anweisungen hinausgehen.

Wie ich bereits erwähnt habe, gehen viele der neuen Tools in der größeren (und großartigen!) Docker-Ökologie davon aus, dass jedes Dockerfile mit genau einem Docker-Image verknüpft ist. Die verschiedenen "Fig"-ähnlichen Orchestrator-Tools da draußen. Und auch viele der neuen und alten Cloud-Lösungen mit spezifischer Unterstützung für Docker haben diese Eins-zu-Eins-Annahme. Zugegeben, sie müssten in der Welt, die durch eine '-f'-Option erstellt wurde, dann nicht nur einen Kontext bekommen - als Tar-Ball zum Beispiel -, sondern auch ein möglicherweise separates Dockerfile. Aber jeder solche Upload entspräche immer noch genau einem Docker-Image.

Wenn wir den Weg gehen, das Dockerfile möglicherweise vom Kontextstamm zu trennen, hoffe ich, dass diese Tools mit diesem Szenario leben:

Each deployment/use of a Docker image is done with an upload of either:

   1. a Dockerfile solely, when no contextual operations are needed
   2. a context tar ball only, containing the context with a top-level Dockerfile
   3. both a context tar ball and a separate Dockerfile

Je länger wir bei dieser starken Kopplung von 'Dockerfile' auf der obersten Ebene des Kontexts bleiben, desto stärker wird dies in der Ökologie verankert sein. Dh, wir sollten jetzt handeln, da sich die Docker-Welt aufgrund der allgemeinen Großartigkeit schnell bewegt.

Und ehrlich gesagt, das ist eine vernünftige und konzeptionell attraktive Annahme, einen Isomorphismus zwischen Dockerfiles und Images zu haben, obwohl ersteres strikt ein Produktraum von Kontextverzeichnissen (aufgetarnt...) und Dockerfiles wäre, die standardmäßig (null, file), wenn nur Dockerfile bereitgestellt wird und (context, context/'Dockerfile'), wenn nur Kontext bereitgestellt wird.

Und sogar für den lokalen Einsatz: Sagen wir, wir wollen Fig zumindest für die lokale Orchestrierung verwenden: Wie würde man das machen? Was man tun müsste, ist, die Images aus einem solchen Dockerfile mit mehreren Builds vorab zu erstellen und dann auf diese Images in Abb. zu verweisen. Nicht optimal.

ein Isomorphismus zwischen Dockerfiles und Images

Diese Annahme wird bereits durch die Verwendung von Dockerfiles durch die Leute in diesem Thread gebrochen. Dh die Verwendung von Skripten, um die Dockerfile manuell zu ersetzen, bevor Docker build ausgeführt wird. Sie haben wahrscheinlich auch ihre eigene Orchestrierung. Bei dieser Funktionsanforderung geht es nicht darum, die Docker-Landschaft zu ändern, sondern darum, Docker für eine bestimmte Verwendungsart zu verwenden.

@hanikesn : zwei Kommentare:

  1. warum wird diese Annahme gebrochen, indem Dockerfiles vor dem Erstellen kopiert werden müssen; es wäre immer noch ein Dockerfile <-> ein Image?
  2. Was ich argumentiere ist, dass ich möchte, dass jede Lösung, die wir hier finden, _mit_ der bestehenden und wachsenden Docker-Landschaft arbeitet, ohne dass zu große Änderungen in dieser Landschaft erforderlich sind; und ich denke, indem wir den erwähnten Isomorphismus behalten, tun wir dies.

Andere Vorschläge hier waren, eine Dockerfile mit mehreren Images zu haben, die möglicherweise Sub-Dockerfiles aufruft. Das würde nicht funktionieren, wenn die meisten Tools (Abb. usw.) Docker derzeit verwenden.

@davber

Verschachtelte Builds lösen nicht die Probleme, mit denen wir konfrontiert sind und die diesen Thread gestartet haben, und halten ihn am Laufen.

Ich schlage diese Lösung vor, auf die ich bereits hingewiesen habe:

$ docker-pre-processor [ --options ... ] . | docker build -

Während --options die Regeln sind, soll der Kontext im (hier) aktuellen Verzeichnis geändert und an docker übergeben werden. Dies muss im laufenden Betrieb erfolgen, indem ein temporäres tar-Archiv erstellt wird, das den Kontext enthält. Auf diese Weise kann der Quellkontext unberührt bleiben. Es ist einfacher, den Präprozessor zu ändern als die Dockerfile-Syntax.

@itsafire

Was ist mit Tools, die heute Dockerfiles erwarten? Sie werden immer reichlicher, indem sie Amazon, Google oder ähnliches verwenden. Und Fig und ähnliche Orchestrierungs-Frameworks.

Wir müssten dann ein standardisiertes „Docker-Pre-Processor“-Tool und die Verwendung eines solchen Tools an diese Frameworks, Anbieter und Tools weitergeben.

Es wäre sicherlich viel einfacher, die richtige Unterstützung von 'Docker' zu haben, zumindest die Option, die diesen Thread auslöst.

@itsafire Jeder mit diesem Problem, der es gelöst hat, verwendet bereits eine Art Präprozessor oder Wrapper um Docker-Build, um dieses Ziel zu erreichen.

Die Fragmentierung dieser Situation steht im Widerspruch zum erklärten Ziel des @docker- Teams der „Wiederholbarkeit“. In dieser und den anderen Diskussionen geht es darum, dieses Problem zu lösen.

1+ Jahr und 130+ Kommentare und das Zählen für ein einfaches Problem, das die meisten Benutzer betrifft... Ich bin beeindruckt. Mach weiter so, Docker!

+1

Tools sollen den Menschen helfen, ihren eigenen Weg zu gehen, aber nicht den "richtigen" Weg aufzuzwingen. Ein einfacher Fall, der mich zu dieser Diskussion geführt hat:

`-- project
     |-- deploy
     |    |-- .dockerignore
     |    |-- Dockerfile
     |    ...
     `-- src

Mein Weg ist es, die Projektwurzel sauber zu halten. Aber ADD ../src und -f deploy/Dockerfile funktionieren nicht. Im Moment habe ich Dockerfile und .dockerignore im Projekt-Root, aber es ist schmerzhaft für mich.

Auf meiner Seite habe ich ein Skript erstellt, das einen Ordner mit den erforderlichen Dateien vorbereitet und die Standardbefehlszeile docker build -t my/image . ausführt, da ich auf das Problem gestoßen bin, dass die .dockerignore Datei von der ADD ignoriert wird

+1 möchte sicher mehrere Dockerfiles in einem einzigen Repository haben. Mein Anwendungsfall: Ein Image ist für die Nutzung und Bereitstellung in der Produktion vorgesehen, ein anderes Image ist eine Berichtsinstanz, die für die Verwendung derselben Backend-Tools und Datenbankkonnektivität entwickelt wurde, jedoch kein Frontend, Web, Systemdienst oder Prozessüberwachung erfordert...

+1 dafür. Ich muss Dateien zu verschiedenen Bildern aus demselben Ordner für verschiedene Server hinzufügen.

+1 Ich mag Docker bisher, aber aufgrund der Art und Weise, wie mein Team eingerichtet ist, brauche ich wirklich eine Möglichkeit, verschiedene Deployables zu erstellen, die einen guten Teil des Codes aus einem Repository teilen. Ich bin nicht besonders daran interessiert, sie alle in einen Uberdocker-Container zu integrieren, da ihre Bereitstellungs-/Freigabezyklen dann unnötigerweise miteinander verbunden sind. Was ist die beste Vorgehensweise, um dies zu umgehen?

@jfgreen :

@ShawnMilo Danke, das scheint eine sehr vernünftige Problemumgehung zu sein.

+1

+1

+1 zu einem -f . Es gibt einen vernünftigen Standard, der, wenn das Flag weggelassen wird, Docker _das Richtige tut._ Für den Fall, dass aus irgendeinem Grund die sehr spezifische Ansicht von _das Richtige_ für einen Benutzer _das Falsche_ ist, gibt es -f . Die obigen Vergleiche mit Tools wie make halte ich für angemessen. make ist auch ein sehr eigensinniges Dienstprogramm, das ursprünglich 1976 geschrieben wurde und als solches eine angemessene Zeit hatte, um ein Feature-Set zu stabilisieren. Ich denke, es ist aufschlussreich, dass in man make das einzige Flag, das in der sehr kurzen Zusammenfassung erwähnt wird, ... -f .

       make [ -f makefile ] [ options ] ... [ targets ] ...

Es gibt kein Problem mit rechthaberischen, ux-zentrierten Dienstprogrammen, aber einige Dinge wie -f sind pragmatische Anspielungen auf die reale Welt, in der die Benutzer leben. Ein Tool sollte Ihr Leben einfacher und nicht schwerer machen. Wenn ich ein Makefile oder ein Shell-Skript schreiben muss, um ein Tool ohne -f umgehen, ist das ein Fehler des Tools. Aus der Anzahl der Benutzer, die sich die Zeit zum Kommentieren genommen und zu +1 gewichtet haben, ist klar, dass die Funktion auch ein Jahr nach ihrer ursprünglichen Einführung einen erheblichen Nutzen hat.

+1

+1 (oder ein offizieller Blogpost mit der empfohlenen Problemumgehung)

+1

+1

@crosbymichael Ich glaube, dies kann jetzt geschlossen werden, da #9707 zusammengeführt wird

SIEG.

Wenn Sie alle diese neue Funktion ausprobieren möchten, können Sie die Binärdateien für Master herunterladen auf:

master.dockerproject.com

Danke @duglin !

:klatschen:

Danke @crosbymichael für die Binärdatei! :+1:

Gut gemacht Jungs! :klatschen:

Also docker build -f Dockerfile.dev . ? edit: ja

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen