Moby: Vom übergeordneten Bild geerbte Eigenschaften zurücksetzen

Erstellt am 6. Jan. 2014  ·  153Kommentare  ·  Quelle: moby/moby

Beim Erstellen eines Bildes möchte ich möglicherweise einige seiner Eigenschaften zurücksetzen, anstatt sie vom übergeordneten Bild zu erben. Es ist sinnvoll, alle Eigenschaften standardmäßig zu erben, aber es sollte eine Möglichkeit geben, sie explizit und selektiv zurückzusetzen, wenn dies sinnvoll ist.

Dies ist eine allgemeinere Lösung für #2210, die nur expose adressiert.

arebuilder kinenhancement statuneeds-attention

Hilfreichster Kommentar

Ich möchte auf jeden Fall eine Möglichkeit haben, VOLUME-Punkte zu entfernen, die von übergeordneten Bildern geerbt wurden.

Angenommen, ich hätte ein Hauptimage für eine Anwendung, die einen externen Mountpoint für persistente Daten verwendet, aber ich wollte auch ein darauf basierendes Image, das stattdessen mit Testdaten vorgefüllt wurde. So wie es ist, kann ich dies nicht tun, wenn das übergeordnete Image VOLUME verwendet, da alle Änderungen/Ergänzungen an diesen Verzeichnissen, selbst wenn diese Änderungen während eines Docker-Builds vorgenommen werden, beim Commit verloren gehen.

Alle 153 Kommentare

Vorschläge zur Syntax willkommen.

Das Beste, was mir einfällt, sind entsprechende Befehle wie UNVOLUME oder allgemeiner -VOLUME (aber das würde mehr Verwirrung stiften und möglicherweise sogar das Missverständnis erzeugen, dass +VOLUME funktionieren sollte, und sollte anders funktionieren als nur VOLUME ).

Ich will so etwas ganz bestimmt (vor allem für VOLUMES). Es ist auch ein wenig verwirrend, dass Dinge wie VOLUME für das Befolgen von RUN-Linien gelten, Dinge wie ENTRYPOINT jedoch nicht. Manchmal ist das sehr nützlich und manchmal nicht, aber eine generische "Vorherige X-Anweisung deaktivieren" könnte die Probleme damit ganz gut lösen.

Gibt es dafür inzwischen einen Workaround? Ich erweitere ein Image mit einem ENTRYPOINT (https://github.com/jagregory/pandoc-docker/blob/master/Dockerfile) und muss den Einstiegspunkt aufheben. Ich habe versucht, Folgendes in meinem Dockerfile zu verwenden:

FROM jagregory/pandoc
ENTRYPOINT [] # this basically gets ignored (bug?)

FROM jagregory/pandoc
ENTRYPOINT [""] # this will make docker try to exec '' (the empty string)

FROM jagregory/pandoc
ENTRYPOINT ["/bin/sh", "-c"] 
# this will only work if docker run args are quoted:
#   docker run dergachev/pandoc "echo a b c"

Danke!

Ich möchte auf jeden Fall eine Möglichkeit haben, VOLUME-Punkte zu entfernen, die von übergeordneten Bildern geerbt wurden.

Angenommen, ich hätte ein Hauptimage für eine Anwendung, die einen externen Mountpoint für persistente Daten verwendet, aber ich wollte auch ein darauf basierendes Image, das stattdessen mit Testdaten vorgefüllt wurde. So wie es ist, kann ich dies nicht tun, wenn das übergeordnete Image VOLUME verwendet, da alle Änderungen/Ergänzungen an diesen Verzeichnissen, selbst wenn diese Änderungen während eines Docker-Builds vorgenommen werden, beim Commit verloren gehen.

Nur um den Kommentar von @dergachev zu aktualisieren, CMD [] und ENTRYPOINT [] funktionierten das letzte Mal, als ich sie vor kurzem getestet habe, und sollten immer noch funktionieren (alles andere wäre reif für die Einreichung von Fehlern).

Sie können alle Einzeloptionsbefehle über . zurücksetzen

ENTRYPOINT []
CMD []
USER 0
WORKDIR /

Dies sollte die verbleibenden, nicht zurücksetzbaren Metadaten als ENV , VOLUME , EXPOSE und vielleicht ONBUILD .

(Das kommt von #8709)

Wenn ich die Sockets 9000-9002 im Parent freigelegt habe, aber 9001 im Child freigeben müsste, müsste ich im Stil von "unsetting" schreiben

EXPONIEREN
AUSSETZEN 9000
EXPOSE 9002

was würde funktionieren aber

UNEXPOSITION 9001

sieht schöner aus.

Ein Vorteil ist, dass es keine EXPOSEs von weiter oben in der Vererbungskette beeinflusst, die ich vielleicht später hinzufügen möchte.

+1 @ codeon-nat

Dies wurde in #8177 besprochen, wir schließen dies aus Mangel an realen Anwendungsfällen.

Warum wird das geschlossen? Es gab 9 Leute, die hier Kommentare abgegeben haben. Ich denke, das wäre eine wirklich nützliche Sache. Die realen Anwendungsfälle können problemlos auf vorhandenen Bildern aufbauen. Manchmal möchten Sie eine Eigenschaft hinzufügen, manchmal möchten Sie sie entfernen. Das ist normal.

Ich stimme zum Beispiel zu, dass ich das Image nginx für einen SSL-Offloader erweitere und UNEXPOSE 80 möchte, aber 443 lasse.

Die Möglichkeit, Ports freizugeben, ist ziemlich wichtig, wenn Sie mehrere Instanzen von beispielsweise nginx ausführen möchten.

Egal, das war nur eine schlechte Konfiguration auf meiner Seite.

(15. April: "Keine realen Anwendungsfälle" Ich bin überrascht, dass Sie sich nicht mindestens einen vorstellen können und schloss dies)

Ich habe ein Basis-Image, das Volumes oder Ports für optionale Software verfügbar macht, und dann FROM in einem anderen Dockerfile, um ein Image zu erstellen, das nichts offenlegen sollte, was es nicht möchte, oder sogar Dinge, die es vom Vorfahren deinstalliert hat. Warum sollten wir diese Einstellungen NICHT entfernen können?

Dafür habe ich auch einen Anwendungsfall. Ich möchte in der Lage sein, ein Image mit einem Datenbank-Snapshot zu erstellen, aber für alle MySQL-Pakete ist VOLUME /var/lib/mysql festgelegt. Es wäre schön, das Volume ausschalten zu können, bei dem die Änderungen an der Datenbank, die in meinem Dockerfile vorgenommen wurden, beim Image bleiben.

Die einzige andere Möglichkeit besteht darin, ein benutzerdefiniertes MySQL-Image vollständig neu zu erstellen, aber das scheint irgendwie verschwenderisch zu sein, da viele andere Leute bereits bessere Standard-Mysql-Server zusammengestellt haben, als ich es könnte.

Hinzufügen eines zusätzlichen Anwendungsfalls - Ich erbe vom offiziellen RabbitMQ-Image, möchte jedoch nur die Websocket-Ports (80 und 443) und nicht den standardmäßigen AMQP-Port (5672) verfügbar machen. Scheint, als ob dies eine ziemlich vernünftige Sache sein sollte?

Hinzufügen eines weiteren Anwendungsfalls. Ich möchte eine Git-Testumgebung mit dem Gogs-Image erstellen, aber es ist mühsam, die Daten beizubehalten, da sie alle in einem Volume gespeichert sind. Es wäre großartig, wenn ich nach dem Einrichten der Umgebung einfach die Lautstärke aufheben und mein Image aufbauen könnte.

+1

erben von der offiziellen php und möchten Sockets anstelle von Ports verwenden, müssen also den exponierten 9000-Port entfernen

Jeder, der Docker in einer nicht trivialen Funktion verwendet hat, wird diese Einschränkungen bei geerbten Containern festgestellt haben.

@shykes @icecrime wie wird das jetzt geschlossen? Ist es mit der aktuellen Syntax zu schwer zu lösen und ist Abwärtskompatibilität erforderlich? Wie ist der Plan?

+1 – realer Anwendungsfall für EXPOSE-Überschreibung hier.

Wenn man bedenkt, dass dies seit über 3 Jahren andauert (ein Problem aus dem Jahr 2013 gefunden wurde), wann werden wir in der Lage sein, exponierte Ports zu entfernen?

+1. müssen in der Lage sein, die Standard-Nginx-Ports 80 und 443 "UNEXPOSE" zu aktivieren.

Für die Leute hier, die nach UNEXPOSE fragen; die EXPOSE Anweisung gibt nur einen Hinweis darauf, welche Ports vom Container verfügbar gemacht werden, _exponiert_ diese Ports jedoch nicht; Sie müssen diese Ports _veröffentlichen_ ( -p / -P ), um sie auf dem Host verfügbar zu machen. Mit anderen Worten; das Weglassen der EXPOSE Anweisung aus einem Dockerfile hat _keine_ direkte Auswirkung auf das Image (Sie können zB immer noch "Port 80" des Containers erreichen).

Wenn Sie zusätzliche Ports freigeben möchten, lassen Sie den Dienst im Container außerdem einfach auf diesen Ports laufen, und dies wird funktionieren.

Stimmt, aber wenn Sie -P verwenden (um alle Ports freizugeben) und Ihr Basis-Image einen Port freigibt, den Sie nicht mehr freigeben möchten, dann stecken Sie fest. Sie müssten wechseln, um -p zu verwenden und alle anderen Ports aufzulisten.

@thaJeztah das ist gut zu wissen. Was ist jedoch der Schaden, wenn UNEXPOSE hinzugefügt wird? Es wäre auch für mich nützlich, wenn auch nur um besser dokumentierte Container zu haben.

@kgx kein Schaden (abgesehen von einer möglichen Funktionserweiterung), wollte aber erklären, dass es kein Sicherheitsproblem ist, nicht "unbelichten" zu können (einige Leute haben diesen Eindruck). UNVOLUME (oder UNSET VOLUME ) steht noch auf meiner persönlichen Wunschliste. :-)

Ich bin amüsiert, dass ich in den ersten 72 Stunden, in denen ich Docker ausprobiert habe, auf dieses Problem gestoßen bin. Jede Konfiguration oder Sprache für jedes andere wichtige Tool, das ich verwende, das irgendeine Art von Vererbung hat, hat eine Art von "Überschreiben des Elternteils".

Hier ist ein Anwendungsfall: Ich verwende das Standard-Docker-Image für go-ethereum und muss in der Lage sein, eine Testversion einzurichten, die sich absolut nie mit der Außenwelt verbinden wird. Ich muss in der Lage sein, eine Verbindung vom Host und anderen Containern herzustellen. Der sicherste Weg, dies zu tun, besteht darin, die Ports zu ändern, da das Programm eifrig versucht, sich mit Peers zu verbinden. Ich muss auch in der Lage sein, CMD und ENTRYPOINT zu überschreiben, um eine "Datenbank einrichten"-Version des Images zu erstellen, die ich einmal ausführe, um das richtige Volume zu erstellen. All dies ist im Dockerfile extrem schwer zu erreichen.

Sie können ihm eine andere IP-Adresse zuweisen... Oder einen anderen Host-Port binden. Das spätere Überfahren von Einstiegspunkt und cmd besteht darin, sie einfach neu zu definieren.

---Gesendet von Boxer | http://getboxer.com

Am 20. Februar 2016 um 08:57:00 GMT schrieb barkthins [email protected] :Hier ist ein Anwendungsfall: Ich verwende das Standard-Docker-Image für go-ethereum, und ich muss in der Lage sein, einen Test einzurichten Version, die sich absolut nie mit der Außenwelt verbinden wird. Ich muss in der Lage sein, eine Verbindung vom Host und anderen Containern herzustellen. Der sicherste Weg, dies zu tun, besteht darin, die Ports zu ändern, da das Programm eifrig versucht, sich mit Peers zu verbinden. Ich muss auch in der Lage sein, CMD und ENTRYPOINT zu überschreiben, um eine "Datenbank einrichten"-Version des Images zu erstellen, die ich einmal ausführe, um das richtige Volume zu erstellen. All dies ist im Dockerfile extrem schwer zu erreichen. – Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.

CMD und ENTRYPOINT können zur Laufzeit überschrieben werden; docker run --entrypoint=foo myimage mycmd . Die Frage hier ist, ob es nützlich ist, während des Tests ein anderes Image mit einem anderen Einstiegspunkt/cmd zu verwenden, da Sie das tatsächliche Image, das in der Produktion ausgeführt wird, nicht _testen_. (nur eine Randnotiz)

Aus diesen Antworten geht hervor, dass die Dockerfile-Datei zugunsten von Befehlszeilenoptionen veraltet ist, zumindest was Entrypoint, CMD, Expose und wahrscheinlich einige andere betrifft. Die Befehlszeile macht bereits Dinge, die das Dockerfile nicht kann, also scheint dies die Richtung zu sein. Wenn dies beabsichtigt ist, verschiebe ich so viele Dockerfile-Informationen wie möglich in die Instanzierungszeit, um die Verwirrung zu reduzieren. Ist das die Absicht?

@barkthins nein, das Dockerfile ist nicht veraltet. Die Verwendung eines Dockerfiles ist immer noch die übliche Methode, um ein Image zu erstellen. Außerdem können Sie CMD und ENTRYPOINT in geerbten Bildern überschreiben. Mein Beispiel sollte zeigen, dass Sie in bestimmten Fällen (z. B. beim Ausführen eines alternativen Befehls für Ihr Image) diese zur Laufzeit überschreiben können.

Von der Dockerfile-Manpage:

     -- EXPOSE <port> [<port>...]
     The EXPOSE instruction informs Docker that the container listens

auf der
angegebenen Netzwerkports zur Laufzeit. Docker verwendet diese Informationen, um
Container über Links miteinander verbinden und _Port einrichten
Umleitung auf dem Host_

  • System.*
    […]
    GESCHICHTE
    *Mai 2014, zusammengestellt von Zac Dover (zdover at redhat dot com) basierend
    auf docker.com Dockerfile-Dokumentation. *Februar 2015, aktualisiert von Brian Goff (
    [email protected])
    zur besseren Lesbarkeit *September 2015, aktualisiert von Sally O'Malley (
    [email protected])

[meine Kursivschrift] scheint irreführend (oder zumindest mehrdeutig), wenn das, was Sie sagen, ist
wahr.

Am Do, 28.01.2016 um 6:43 Uhr, Sebastiaan van Stijn <
[email protected]> schrieb:

Für die Leute hier, die um UNEXPOSE bitten; nur die EXPOSE-Anweisung
gibt einen _Hinweis_, welche Ports vom Container verfügbar gemacht werden, aber nicht
tatsächlich _expose_ diese Ports; Sie müssen diese Ports _veröffentlichen_ (-p / -P)
um sie auf dem Host freizugeben. Mit anderen Worten; Weglassen der EXPOSE-Anweisung
aus einem Dockerfile hat _keine_ direkte Auswirkung auf das Image (Sie können
noch zB "Port 80" des Containers erreichen).

Wenn Sie zusätzliche Ports freigeben möchten, machen Sie einfach die
service im Container auf diesen Ports ausgeführt, und dies wird funktionieren.


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

Derzeit Co-Autor eines Buches über Docker: Erhalten Sie 39% Rabatt mit dem Code 39miell
http://manning.com/miell/?a_aid=zwischenzugs&a_bid=e0d48f62

thaJeztah Mein Punkt und ich denke, der Punkt dieses Threads ist, dass die Vererbung inkonsistent ist. Ja, Sie können ENTRYPOINT und CMD überschreiben, aber EXPOSE fügt Belichtung hinzu. Sie können die Belichtung des übergeordneten Elements nur in der Befehlszeile ersetzen. Ich habe andere Befehle nicht untersucht, um zu sehen, ob es ein drittes Verhalten gibt. Es ist auch nicht dokumentiert, welche Befehle den Befehl eines Elternteils erweitern oder ersetzen.

@thaJeztah wir brauchen UNEXPOSE

Es gibt mehrere Lösungen, die die Container-Metadaten lesen und zusätzliche Upstream-Konfiguration bereitstellen. Beispielsweise; Mit HAPROXY muss ich EXCLUDE_PORTS=8080 , um es zu blockieren, wenn ich versuche, dynamisch den Zugriff auf diesen Port in meinen Tomcat-Apps bereitzustellen.

Entwickler sehen sich die exponierten Ports an und treffen Annahmen über das Verhalten des Containers. Zum Beispiel habe ich ein Basis-Image, das Tomcat erweitert (EXPOSE 8080), aber das Image verwendet einen anderen Port als den Standard (EXPOSE 8888). Wenn Sie einen Webserver zu einem zusammengesetzten Image hinzufügen (z. B. mit NGINX und Tomcat), stellen Sie Inhalte über HTTP bereit (EXPOSE 80 und EXPOSE 443).

Im letzteren Beispiel können Sie am Ende ein Bild erhalten, das sich selbst als Belichtung von 8080, 8888, 80 und 443 dokumentiert, wobei nur 80/443 relevant ist.

Dies sind echte Probleme, wie die Tatsache zeigt, dass ich Entwicklern in unserer Community trotz sehr spezifischer Dokumentation immer wieder Dinge erklären muss; wer braucht dokumentation, wenn man nur das bild anschauen kann? <-- jeder, wenn das Bild das Falsche selbst dokumentiert.

Es gibt Problemumgehungen für dieses Problem, aber es handelt sich um Problemumgehungen. Ist das ein wichtiges architektonisches Problem? Warum kann Docker keine elegantere Lösung für dieses echte Problem in Betracht ziehen?

Wie ist der Stand dazu?

@BillBrower- Status ist, dass sie das Problem geschlossen haben, ohne eine Begründung dafür zu liefern, warum sie glauben, dass es kein Problem ist. Für viele von uns ist es offensichtlich weiterhin ein reales Problem, das unser tägliches Leben quält ;)

@modius @BillBrower auch wenn es geschlossen ist, können die Dinge immer noch einmal überdacht werden; grundsätzlich "nein ist temporär", aber "ja ist für immer" beim Zusammenführen/Implementieren von Features. Wenn es also Bedenken hinsichtlich eines Features gibt, ist die richtige Wahl für Betreuer, "nein" zu sagen.

Die PR, die dies implementierte, wurde geschlossen, weil es Betreuer gab, die sich über die Funktion nicht sicher waren und nach aktuelleren Beispielen für ihre Verwendung suchten. https://github.com/docker/docker/pull/8177#issuecomment -93587164

Wir schließen dies, da wir größtenteils anderer Meinung sind, aber bitte zögern Sie nicht, uns in den Kommentaren zu beweisen, dass wir falsch liegen, und wir können es uns noch einmal überlegen

Das war vor über einem Jahr, also haben sich die Dinge möglicherweise geändert; Ich werde dieses Thema erneut öffnen und es in der nächsten Betreuersitzung zur Sprache bringen. (Beachten Sie, dass dies aufgrund der DockerCon und der ausstehenden Version 1.12 etwas länger dauern kann als üblich)

Danke, @thaJeztah. Das macht viel Sinn. Ich weiß es zu schätzen, dass Sie die Gründe für die ursprüngliche Entscheidung erklären und skizzieren, was Sie sehen müssen, wenn wir dies wollen.

Ein Anwendungsfall für die _UNVOLUME_-Anfrage

Vor allem, weil derzeit ein benutzerdefinierter Volume-Treiber für ALLE Volumes des angegebenen Containers gilt.

Ich hatte den Fall mit einem EFS-Volume-Treiber: funktioniert gut, wenn ich die Volume-Bindung beim Start angebe. Wenn ich keine Bindung festlege, schlägt dies fehl, da versucht wird, die NFS-Freigabe von einer automatisch generierten UUID zu mounten. Das bedeutet, dass ich für alle meine Volumes eine Bindung bereitstellen muss, auch für die, die mir egal sind, die beispielsweise von einem übergeordneten Image erstellt wurden.

Die einzige Problemumgehung besteht derzeit darin, beim Start alle Volumes, die ich nicht benötige, an einen leeren Unterordner derselben EFS-Freigabe zu binden.

Hinweis: Ich kann den Befehl docker volume nicht verwenden, da dies alles von Marathon gestartet wird und in einem einzigen docker run-Befehl verwendet werden sollte.

+1 UNBELICHTUNG erforderlich

+1 für UNBELICHTUNG

+1 für UNBELICHTUNG

+1 für UNBELICHTUNG

+100 für UNBELICHTUNG

+9000 für UNBELICHTUNG

+∞
Zum Beispiel verwende ich das offizielle Repository nginx (FROM nginx:stable) , das in Dockerfile enthält:

EXPOSE 80 443

Aber ich möchte in eine andere Ebene entfernen, den Port 80. Beispiel:

UNEXPOSE 80

Bitte!
Diese Funktion hinzufügen!!!!

@frekele , wenn ich deine Mutter oder dein Vater wäre, würdest du es nicht

UNBELICHTET +++
Sehr notwendige Funktion!

Bitte, Sie müssen nicht alle anderen mit E-Mail-Benachrichtigungen spammen und Sie müssen die Diskussion definitiv nicht mit all diesen +1-Kommentaren überladen. Sie können einfach mit 👍 auf die Problembeschreibung reagieren, um Ihr Einverständnis auszudrücken.

@underyx das ist offtopic, aber ich beiße, weil ich immer wieder Leute sehe, die das sagen. Es ist nuancierter als Sie denken. Für viele größere Teams ist die Anzahl der Kommentare zu einem Thema die einzige Möglichkeit, das Engagement zu messen, da Reaktionen als soziales Feature konzipiert sind – nicht als Abstimmungsmechanismus und daher keine zuverlässige Möglichkeit sind, Berichte über die GH-API zu erstellen (z unter anderem nicht sortierbar). Außerdem abonniere ich durch das Hinzufügen eines Kommentars automatisch den Thread, was in den meisten Fällen das ist, was ich will - sonst müsste ich auf 👍 klicken _und_ auch auf "Abonnieren" klicken.
Siehe https://github.com/isaacs/github/issues/9#issuecomment -195120703 (der ganze Thread ist gut, aber zu diesem Zeitpunkt fügte GH Reaktionen hinzu).
Jetzt lass uns die Diskussion nicht überladen ;)
/offtopic .

Wir haben dieses Problem im Betreuertreffen besprochen, und im Allgemeinen sind wir in Ordnung, wieder daran zu arbeiten.

@duglin bist du vielleicht daran interessiert, daran zu arbeiten?

Ich weiß nicht, ob ich noch Zeit habe, aber nur um es zusammenzufassen .... basierend auf den obigen Kommentaren glaube ich, dass die Anforderung darin besteht, sicherzustellen, dass die Leute Folgendes löschen/deaktivieren können:

EXPOSE  (all or specific one)
ENV  (specific - not sure we need to clear all yet)
LABEL  (ditto)
VOLUME  (all or just specific paths? probably both)
CMD  (possible but only using the json format)
ENTRYPOINT  (possible with json format)

Habe ich etwas vergessen?

+10000 für UNVOLUME

@duglin Ich denke, es wäre am besten, mit denen zu beginnen, die derzeit _nicht_ möglich sind und am besten nachgefragt werden ( EXPOSE , VOLUME ). Ich habe nicht viele Anfragen für die anderen gesehen (aber nicht dagegen).

Die ursprüngliche PR verwendete UNSET <SOMETHING> , wurde aber später in UN<SOMETHING> geändert. Ich persönlich mochte das erste mehr (generischer), aber @shykes bevorzugte UN<SOMETHING> , nicht sicher, ob sich das geändert hat.

UNVOLUME wäre nett.

Mein Anwendungsfall: Ich verwende das mysql Image und möchte meine im Verzeichnis /var/lib/mysql enthaltene Datenbank in ein neues Image übertragen, kann dies jedoch nicht, da es in der übergeordneten Dockerfile-Datei als Volume deklariert ist.

@thaJeztah Ich finde UNSET <something> einfacher zu lesen und nicht so seltsam; keine Notwendigkeit, Wörter zu erfinden. Es ist auch bekannt für Scripting-Leute. Könnte man auch machen

UNSET  EXPOSE VOLUME LABEL

Mein Beispiel,

Ich richte eine Dokuwiki-Installation ein. Das von mir gewählte Bild zeigte alle potenziellen Konfigurationsvolumina. Ich möchte meine Installation anhand dieses Basisimages anpassen. Da Volumes verfügbar gemacht werden, kann ich die PHP-Konfigurationsdateien zum Zeitpunkt der Imageerstellung nicht ändern.

Ich kann das Basis-Image ändern, um diese Volumes UNVOLUME zu machen, aber dann muss ich dieses Image für immer beibehalten ...

+1 für UNBELICHTUNG :)

+1 für UNVOLUME oder besser noch UNSET VOLUME.

+1 für UNVOLUMEN. Das könnte jetzt für mich nützlich sein. Könnte auch in Universitätsszenarien nützlich sein, in denen Studenten hochfahren, ohne sich Gedanken über das Mounten von Volumes machen zu müssen.

ohne sich Gedanken über das Mounten von Volumes machen zu müssen.

Ich glaube nicht, dass es dafür benötigt wird; eine VOLUME Definition in einem Dockerfile erstellt automatisch ein "anonymes" Volume aus dem Inhalt an dieser Stelle im Image.

@duglin ,

@runcom go for it - konnte noch keine Zeit finden.

Zur Erinnerung, ein UNENV Befehl wäre immer noch nützlich, um Umgebungsvariablen selektiv aufzuheben (z. B. um mit einem Volume abzugleichen, das gleichzeitig UNVOLUME d ist). Eine nicht gesetzte Variable ist nicht dasselbe wie eine auf leer gesetzte Variable, insbesondere wenn sie mit set -ue in der Shell verwendet wird.

Es wäre möglich, VOLUME und EXPOSE von offiziellen Bildern zu entfernen, wenn
sie sind ein problem.

Am 28. Januar 2017 um 21:23 Uhr schrieb "henryptung" [email protected] :

Zur Erinnerung: Ein UNENV-Befehl wäre immer noch nützlich, um
selektiv Umgebungsvariablen aufheben (z. B. um mit a . abzugleichen)
Lautstärke, die gleichzeitig UNVOLUMEd ist). Eine nicht gesetzte Variable ist nicht die
wie eine Variable, die auf leer gesetzt ist, insbesondere wenn sie mit set -ue in . verwendet wird
Hülse.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/3465#issuecomment-275875623 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAdcPAKP1tii706MY-8MxVPSFLTFme8Dks5rW7HggaJpZM4BXt2-
.

+1 für UNVOLUME

+1 für UNVOLUME

Mein Anwendungsfall für UNVOLUME:

Verwenden des Bibliotheks-/Worpress-Image in einem S2I-Szenario, in dem die Website-Quelle nach /var/www/html kopiert wird

VOLUME unterdrückt dies, indem ein leeres FS auf dem resultierenden Image bereitgestellt wird. -> Bibliothek/Wordpress kann nicht verwendet werden.

@groulot Wenn Sie ein Volume nicht explizit mit --volume darüber mounten, wird der Inhalt des Images bei der Containererstellung in das Volume kopiert.

Der Befehl docker run initialisiert das neu erstellte Volume mit allen Daten, die an der angegebenen Position im Basisimage vorhanden sind.

https://docs.docker.com/engine/reference/builder/#/volume

Es gibt eine hackige Problemumgehung mit Docker Save/Load, siehe http://stackoverflow.com/q/42316614/808723

+1 für UNVOLUME

Ich möchte die Begründung von @modius für die Möglichkeit der UN-EXPOSE wiederholen. Eines der ersten Dinge, an denen sich Entwickler festhalten, wenn sie Docker lernen, ist die Eingabe von docker ps zu sehen, was mit ihren Containern vor sich geht. Der Standardport wird als verfügbar angezeigt. Entwickler sind an die Standardports für Dinge aus ihren lokalen oder Testumgebungen gewöhnt, die sie in einer Welt vor Docker eingerichtet haben. Daher ist die Einführung von Docker schwierig, da sie den Standardport sehen und davon ausgehen, dass er funktioniert – aber tatsächlich sind sie es keine Verbindung zum Docker-Container.

+1 für UNVOLUME, UNEXPOSE, UNENV, ...

Sieht so aus, als wäre dies schon seit einiger Zeit geöffnet. Gibt es hier Traktion?
Ich möchte auch das offizielle PHP-fpm-Alpin-Image und UNIX-Sockets anstelle von TCP-Port 9000 verwenden.
Kann die EXPOSE vom übergeordneten Element nicht überschreiben und möchte dieses Bild lieber nicht erstellen, um die EXPOSE loszuwerden.

+1

+1

Würde die Möglichkeit lieben, einen VOLUME-Befehl aufzuheben. Das offizielle Wordpress-Image legt seine gesamte Codebasis zwangsweise in ein Volume - ich würde es vorziehen, nur ein Volume für das wp-content/uploads-Verzeichnis zu haben, damit der Rest der Codebase in das Image eingebrannt werden kann.

Beim Bereitstellen eines Images im Kubernetes-Cluster, das den Root-Zugriff einschränkt, kann auf VOLUME-Verzeichnisse nicht zugegriffen werden. Die Lösung besteht darin, die im übergeordneten Image definierten Volumes zu überschreiben

+1 von mir

Anwendungsfall für UNEXPOSE

Angenommen, ich habe vier Docker-Hosts und möchte 16 Maven Tomcat-Container ausführen, die alle standardmäßig den internen Port 8080 verwenden.

Stellen Sie sich nun vor, ich verwende den Registrator mit Rancher CNI - was mich an den internen Port sperrt.
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
Dies bedeutet, dass ich nur einen internen 8080-Port pro Host ausführen kann. (Da ich 8080:8080 Port-Mappings machen muss)

In dieser Situation reicht die interne -> externe Portzuordnung von Docker nicht aus, um mein Problem zu lösen. Ich muss tatsächlich die interne Portzuordnung überschreiben, vorzugsweise ohne den ursprünglichen Container neu zu erstellen.

Julian, ich weiß nicht, wie Sie eine 1-zu-1-Zuordnung haben. Für mich Registrator als
hat nichts mit dem Routing des Datenverkehrs zu tun, der nur registriert und abgemeldet wird
Container laufen. Zum Beispiel verwende ich es so, wie es der Registrator beibehält
eine Etcd-Instanz, indem Sie die von Docker zugewiesene IP und den exponierten Port in
dort. Dann wird mit confd eine Etcd-Instanz überwacht und die nginx aktualisiert
config in einem eigenen Container.
Am Sa, 17. Juni 2017 um 04:06, Julian Gamble [email protected]
schrieb:

Anwendungsfall für UNEXPOSE

Angenommen, ich habe vier Docker-Hosts und möchte 16 Maven Tomcat ausführen
Container, die alle standardmäßig den internen Port 8080 verwenden.

Stellen Sie sich jetzt vor, ich benutze den Registrator mit Rancher CNI - was mich sperrt
zum internen Port.
Gliderlabs/Registrator#541 (Kommentar)
https://github.com/gliderlabs/registrator/issues/541#issuecomment-305012416
Dies bedeutet, dass ich nur einen internen 8080-Port pro Host ausführen kann. (Seit ich habe
um 8080:8080 Portzuordnungen durchzuführen)

In dieser Situation reicht die interne -> externe Portzuordnung von Docker nicht aus
um mein Problem zu lösen. Ich muss tatsächlich die interne Portzuordnung überschreiben,
vorzugsweise ohne den Originalbehälter wieder aufzubauen.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/3465#issuecomment-309189149 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/ABrq2QGgY81wbePOBKbkTSjpUSoPIocuks5sE0LCgaJpZM4BXt2-
.

Hallo Bradley,

Danke, dass du dir das angesehen hast. Ich verwende den Registrator in Kombination mit ipsecurity, das in Rancher integriert ist. Wie Sie dem Link hier entnehmen können:
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
Die Möglichkeit, externe Ports im Registrator in Rancher-geplanten Containern anzuzeigen, war eingeschränkt. Dies bedeutete, dass Sie nur interne Ports verwenden konnten.

Sie können sehen, dass Benutzer hier Angst haben, nach einer Lösung zu suchen:
https://forums.rancher.com/t/do-you-kill-registrator/5152

Und hier ein Lösungsvorschlag:
https://github.com/cabrinoob/rancher-registrator
(Was für manche Leute nicht machbar war).

Sie können mehr finden, wenn Sie bei Google nach "Registrator Rancher" suchen.

Sie empfehlen Ihnen, den Registrator in einem "internen" Modus auszuführen, in dem Sie Ihre internen Ports 1:1 Ihren externen Ports zuordnen. Dies führt zu dem Problem mit UNEXPOSE - die internen Ports gehen schnell aus.

Mein Punkt ist, dass ipsecurity, das für das Intra-Host-Docker-Container-Netzwerk verwendet wird, zu einem Anwendungsfall führen kann, bei dem Sie in internen Ports gesperrt sind, die 1:1 externen Ports in Docker zugeordnet sind. Dazu benötigen Sie einen UNEXPOSE Befehl.

Danke, dass du dir das angesehen hast.

Beifall
julianisch

3,5 Jahre sind vergangen und keine Fortschritte in dieser Frage?...

+10086 für UNBELICHTUNG. Manchmal ist das übergeordnete Image möglicherweise nicht offiziell, es verwendet inoffizielle Ports, wir sollten die Möglichkeit haben, die Ports zu überschreiben.

@pumba-lt
Ich wette, der Grund dafür, dass dies keine Lösung findet, ist, dass sie nicht wissen, wie man es technisch macht.

Es erhöht auch die Komplexität der Dockerfile-Sprache, wenn es klare Problemumgehungen gibt. Schieben Sie nicht so viel Konfiguration in das übergeordnete Dockerfile und belassen Sie es stattdessen für die erbenden Images. (auch bekannt als: Beenden Sie die Beschaffung zufälliger Bilder auf dem Docker-Hub :D)

Seit Docker 17.05 gibt es auch eine neue Möglichkeit, mehrstufige Builds durchzuführen, die dieses Problem weitgehend überflüssig macht (dies ist ein einzelnes Dockerfile ):

# First import the original image
FROM nginx AS source-image

# Second step of the build, start with an empty image
FROM scratch
# Copy the data from the original image
COPY --from=source-image / /
# Re-define all the config
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]

BEARBEITEN: Vergessen zu sagen, dass die zweite Lösung alle vorherigen Ebenen zerquetscht. Ich denke nicht, dass es eine große Sache ist, aber es ist gut zu wissen.

@zimbatm - Das ist großartig!

Ich wette, der Grund dafür, dass dies keine Lösung findet, ist, dass sie nicht wissen, wie man es technisch macht.

Die Änderung selbst ist nicht zu kompliziert; eine Umsetzung findet sich in dieser PR; https://github.com/moby/moby/pull/8177. Damals gab es keinen Konsens, aber wenn Sie meinem Kommentar vom Januar folgen; https://github.com/moby/moby/issues/3465#issuecomment -247405438, die Dinge haben sich geändert und (sofern die Leute ihre Meinung seitdem nicht geändert haben) würden wir einen Beitrag zur Umsetzung annehmen.

Warum es noch nicht da ist; einfach, weil niemand Zeit hatte, damit zu beginnen, aber wenn jemand interessiert ist, wird es höchstwahrscheinlich angenommen.

@zimbatm Ja, Ihr Beispiel würde das direkte Problem lösen. nginx als übergeordnetes Element verwenden, sodass möglicherweise mehr Bilder heruntergeladen werden müssen. Beispielsweise;

Das ursprüngliche nginx-Bild:

$ docker inspect nginx -f '{{json .RootFS.Layers}}' | jq .

[
  "sha256:54522c622682789028c72c5ba0b081d42a962b406cbc1eb35f3175c646ebf4dc",
  "sha256:1c3fae42c5007fd0e70309b5b964eb5d49046562bd425424da734784098894e7",
  "sha256:87823f21b7939eac6e099fa878871a806c1904a7698793edb63bf6e5f5371e1f"
]

Und das von Ihnen erstellte nginx-Image;

$ docker inspect nginx2 -f '{{json .RootFS.Layers}}' | jq .
[
  "sha256:9a71ba430225d4f24e0d57837a71b6b2b68bf88ca7530c0a89c98783c98531b5"
]

Danke für das Update @thaJeztah

Darf ich meinen Verwendungsvorschlag wiederholen

UNSET XXXX

anstatt neue und seltsame Vokabeln zu erfinden (zB: UNVOLUME).

Auf diese Weise könnten wir auch mehrere Eigenschaften in einer Zeile aufheben.

UNSET VOLUME EXPOSE LABEL

Ich persönlich bin damit einverstanden, UNSET tun, das eine oder andere wird wahrscheinlich keine große Veränderung sein, also überlasse ich das dem Überprüfungsprozess, wenn eine PR eintrifft

Hallo, selbst wenn ich FROM zum zweiten Mal verwende, wie behalte ich alles aus dem übergeordneten Image, außer dass einige der im übergeordneten Docker-Image angezeigten Ports nicht verfügbar gemacht werden? gibt es dazu eine offizielle Resolution, lasst uns das entweder akzeptieren und bearbeiten oder ablehnen

lasst uns das entweder akzeptieren und bearbeiten oder ablehnen

@rajiff siehe meinen Kommentar oben https://github.com/moby/moby/issues/3465#issuecomment -313549657 Beiträge sind willkommen

Die Änderung selbst ist nicht zu kompliziert; eine Umsetzung findet sich in dieser PR; #8177. Damals gab es keinen Konsens, aber wenn Sie meinem Kommentar vom Januar folgen; #3465 (Kommentar), die Dinge haben sich geändert und (es sei denn, die Leute haben ihre Meinung seitdem geändert) würden wir einen Beitrag zur Umsetzung annehmen.

Wenn sich also der Konsens geändert haben könnte, warum nicht einfach #8177 wieder

Wenn sich also der Konsens geändert haben könnte, warum nicht einfach #8177 wieder öffnen?

Diese PR wurde vor über drei Jahren eröffnet; der Code gilt nicht mehr

Anstatt speziell einen UNsomething-Befehl verwenden zu müssen,
Warum nicht den FROM-Befehl verbessern und es ermöglichen aufzulisten, was wir eigentlich erben wollen?

Wir könnten so etwas gebrauchen:
FROM baseimage (VOLUME, EXPOSE, PORT, ..)
oder wenn du es wirklich mit Verneinung willst:
FROM Basisbild (*, -VOLUME, -EXPOSE)
oder eine bessere Syntax haben ;)

Mir scheint, dass all dies in erster Linie Teil des FROM-Befehls sein sollte.

Ändern des Volumes aus dem Dockerfile: Wenn Build-Schritte die Daten innerhalb des Volumes ändern, nachdem es deklariert wurde, werden diese Änderungen verworfen.

Das scheint nicht ganz richtig zu sein. Sie können dies immer noch tun:

VOLUME /avolume/subdir
WORKDIR /avolume
COPY ./Dockerfile /avolume/subdir

Ich weiß jedoch nicht, ob man damit ein Volume rückgängig machen kann.

Das Überschreiben des übergeordneten Images / Containers ENTRYPOINT funktioniert in den neuesten Versionen nicht.

17.09.1-ce Version

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

seit 17.10.0-ce Version

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[/bin/bash]

UNSET ENTRYPOINT funktioniert auch nicht.
Ist es ein Fehler?

@alexey-igrychev kannst du dafür ein separates Thema öffnen? Das Problem, das Sie kommentieren, ist eine _Funktionsanforderung_ zum Implementieren von UNSET xx Anweisungen im Dockerfile. (Die Anweisung UNSET ist noch nicht implementiert, daher wird dies erwartet.)

Um dieses Problem zu umgehen, scheint die Verwendung von [""] anstelle von [] für den Einstiegspunkt zu funktionieren;

IMAGE=$(docker commit -c "ENTRYPOINT [\"\"]" experiment)
docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

Ich brauche auch eine Möglichkeit, das Volumen aufzuheben, damit ich ein Datenbankabbild erstellen kann, das mit Tabellen und Daten vorgeladen ist.
Leider ist das Basis-Image privat (Oracle) und daher kann ich nicht einmal das Basis-Dockerfile kopieren, da ich keinen Zugriff darauf habe. Ich kann das Bild nur erweitern.
In dieser Ausgabe sind Tonnen von +1 und Anwendungsfällen aus der realen Welt aufgeführt, und es wurden mehrere PRs dafür erstellt, und dennoch wurden die PRs geschlossen. Was müssen wir also tun, um diese Funktion zu erhalten?

@veqryn seit dem erneuten Öffnen dieses Problems hat niemand angefangen, an einem Pull-Request zu arbeiten; der vorhandene Pull-Request wurde nicht mehr sauber auf der Code-Basis angewendet, so dass ein neuer geöffnet werden muss; wenn jemand daran interessiert ist, daran mitzuarbeiten, dann kann es wieder losgehen.

Siehe meine früheren Kommentare; https://github.com/moby/moby/issues/3465#issuecomment -247405438

Wir haben dieses Problem im Betreuertreffen besprochen, und im Allgemeinen sind wir in Ordnung, wieder daran zu arbeiten.

@duglin bist du vielleicht daran interessiert, daran zu arbeiten?

Und https://github.com/moby/moby/issues/3465#issuecomment -313549657

Warum es noch nicht da ist; einfach, weil niemand Zeit hatte, damit zu beginnen, aber wenn jemand interessiert ist, wird es höchstwahrscheinlich angenommen.

Mein Anwendungsfall stammt aus docker-compose.yaml: Ich hätte gerne eine Compose-Datei für die Entwicklung mit Überschreibungen für die Produktion, die einen TLS-Reverse-Proxy, Maven-Repository, hinzufügt, PORT 80/443 übernimmt, Port 80 und 5432 entsperrt die Entwicklung Compose-Datei verfügbar macht. Oder eine Compose-Datei für die Produktion mit Entwicklungsüberschreibung.

Der Add-Only-Charakter der Layering Compose-Dateien, die von Dockerfiles geerbt wurden, erschwert das Systemdesign. Es wäre wirklich cool, wenn man einige Parameter zurückziehen könnte, oder wenn ich einfach einen anderen Container mit aktiven Überschreibungen bauen würde. Ich bin nicht wählerisch, wie es unter der Haube bei Docker-Compose funktioniert.

Danke @thaJeztah - könnten Sie uns bitte auf die Codezeile hinweisen, die Ihrer Meinung nach der Ort ist, an dem Sie mit dem Lesen beginnen sollten, um dies mit einem Pull-Request zu beheben?

Ich habe selbst nicht viel am Builder-Code gearbeitet, aber Änderungen sollten wahrscheinlich im https://github.com/moby/moby/tree/master/builder-Paket sein .

Diese Ausgabe hat 3 Jahre! Ist es so schwer, sich auf ein so grundlegendes Feature zu einigen, oder übersehe ich etwas?

@caruccio ja, du vermisst etwas: scrolle 4 Kommentare nach oben https://github.com/moby/moby/issues/3465#issuecomment -356988520

Ich habe auch ein paar Anwendungsfälle (einen ein persönliches Projekt und der zweite ein Arbeitsprojekt), in denen ich eine VOLUME , EXPOSE und ENTRYPOINT Anweisung von a . überladen möchte Elternbild.

Während ich einen Workaround für ENTRYPOINT indem ich einfach einen neuen leeren Einstiegspunkt mit ENTRYPOINT [] setze und wahrscheinlich lernen kann, damit zu leben, EXPOSE zu ignorieren, ... mein Kopf darüber, wie man VOLUME Definitionen nicht erbt.

Ich bin gerade in meiner Codebasis auf dieses Problem gestoßen, bei dem das übergeordnete Image ein VOLUME hatte, was bedeutet, dass alle meine Änderungen an diesem Volume in einem untergeordneten Image verworfen wurden. Ich dachte 2 Tage lang verrückt zu werden, bis ich endlich meinen Weg zu diesem Thema gefunden habe. Könnte das bitte jemand umsetzen.

Es gibt eine Abhilfe.

Sie können jederzeit docker save image -o image.tar , dieses Archiv entpacken, die Metadaten bearbeiten und für ein docker load -i image2.tar packen. Auf diese Weise kann man ein Image2 erstellen, das keine der vorherigen VOLUME-Deklarationen enthält.

Da ich diese Schritte ziemlich regelmäßig ausführen muss, habe ich ein kleines Skript erstellt, das bei der Bereinigung eines Drittanbieter-Images hilft. Schau mal bei docker-copyedit

Fantastische Arbeit @gdraheim ! Eine praktikable Lösung in <250 Python-Linien.

@gdraheim wow, das ist großartig! Aus der README:

Der Wunsch, ALLE VOLUMEN ZU ENTFERNEN, entstand aus der Tatsache, dass ich ein getestetes Image für lokale Tests herunterladen wollte, bei denen der Datenteil auch in die Historie übernommen werden sollte, um sowohl Programm als auch Daten in einen definierten Zustand zurückzusetzen, damit ein anderer Der Testlauf beginnt am exakt gleichen Prüfpunkt.

Dies ist auch unser Anwendungsfall.

Ich habe docker-copyedit erweitert, um alle Metadateneinträge eines Bildes abzudecken, damit es auch über die problematischen Fälle der EXPOSE- und VOLUME-Listen hinaus mit allen geerbten Eigenschaften arbeiten kann. Das wären Benutzer-, Arbeitsverzeichnis, Labels, Umgebungseinstellungen für Dinge, die oft gesehen werden. Das Kopieren von ENTRYPOINT nach CMD ist auch eine Änderung, die ich ziemlich regelmäßig mache. Sie müssen keinen Docker-Build-Zwischenschritt mehr machen, gehen Sie einfach zu docker-copyedit . ;)

Die Zeit, die das Docker-Team verwendet hat, um dieses Problem zu verfolgen und wiederholt zu ignorieren, hätte wahrscheinlich ausgereicht, um es stattdessen zu beheben.

Können wir dies jetzt bitte wieder öffnen, nachdem offensichtlich eine Menge Benutzer dies angefordert haben ...
oder zumindest ein vernünftiges Argument dagegen geben, nicht nur alle Anwendungsfälle zu ignorieren (ich möchte auch eine Portierung unexponieren und nur um eine saubere Docker-PS-Ausgabe ohne zu ficken (80/80/tcp) zu erhalten, bevor ich mein eigenes Image aufbaue.. .. (was für Nicht-Opensource-Dockerfiles schwieriger ist)

Das Thema ist noch offen; Es ist Open Source; Beiträge sind willkommen https://github.com/moby/moby/issues/3465#issuecomment -356988520

Denke ich richtig, dass dies jetzt in Dockerfile-Befehlsinfrastruktur .

Ich bin auch ein Fan von UNSET , wie

UNSET EXPOSE 9000

oder

UNSET LABEL foo

Ich schaue mir also Befehle an, die Unterbefehlsformen haben, wie das HEALTHCHECK CMD Formular, und ich stelle fest, dass HEALTHCHECK bereits eine nicht festgelegte Form hat ...

HEALTHCHECK NONE

Dies ist eine interessante Wahl, aber HEALTHCHECK definiert auch nur 1 Konfiguration (und überschreibt mit der neuesten), es erlaubt nicht, mehrere zu definieren, wie LABEL , EXPOSE , und VOLUME tun.

Ich frage mich nur, wie diese interagieren sollen oder ob es eine andere Art von NONE Formular gibt, die funktionieren könnte.

Eine Möglichkeit zum Entfernen offengelegter Ports ist wirklich erforderlich, um zu steuern, was bei der Verwendung von Hostnetzwerken offengelegt wird.

+1 AUFSTELLEN []

Also .... für das Docker-Team, das seit 5 Jahren nicht in der Lage ist, den UNSET-Operator zu implementieren, fantastisch

Wie @AnthonyMastrean sagte, sollten wir dieses Problem in das Projekt moby/buildkit ?

Es gibt auch eine PR, gut dokumentiert und getestet, aber nicht zusammengeführt. Sollten wir diese PR auch verschieben/umbasieren?

Diese Funktion wäre sehr dankbar und behebt ein Problem mit nginx-basierten Images in Azure.

UNSET , CLEAR , RESET , OVERRIDE , IGNORE wäre ok - ich würde UNxxx vermeiden, weil das würde die Liste der reservierten Schlüssel zum Unterstützen und Dokumentieren duplizieren.

Was ignoriert/zurückgesetzt werden soll, könnte auch angegeben werden, wenn FROM , zB

FROM nginx:1.13 IGNORE EXPOSE, ENTRYPOINT

Ich schlage eine weitere Problemumgehung vor, bei der mehrstufige Builds verwendet werden.
Es kopiert alle Dateien vom Originalbild in das neue Bild, jedoch ohne Metadaten.

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

Ich kann nicht glauben, dass ich nicht daran gedacht hatte. Das ist eigentlich ziemlich gut @kotofos. Sie verlieren die Schichten des Upstream-Containers, aber das ist kein großer Verlust.

@kotofos Warum nicht FROM scratch as postgres ?

@farcaller guter Fang. Scratch wäre definitiv besser, da du das gesamte Dateisystem überschreibst

Zuletzt habe ich es getestet, COPY --from=xxx ... würde das Dateisystem nicht erhalten
Eigentum, daher sollten Sie mit dieser Problemumgehung vorsichtig sein.

@tianon Sie haben --chown Flag verwenden können, um den Benutzer, den Sie ausführen, wie im Container festzulegen

https://docs.docker.com/engine/reference/builder/#copy

Dies geht auf das Jahr 2014 zurück. Es ist 5 Jahre her und es scheint, als ob es in naher Zukunft kein allgemeines "Unset" oder "Reset" für alle Properties geben wird. Ich bevorzuge auch einen generischen Ansatz, aber es gibt einfach zu viele Dinge zu beachten und wirklich: Es wird nicht so schnell passieren.

Also: können wir zumindest eine "UNEXPOSE" bekommen, um alle diese geöffneten Ports zu schließen, oder zumindest das gleiche Verhalten wie bei CMD und ENTRYPOINT (letzter gewinnt)? Es ist die am häufigsten angeforderte "unset"-Eigenschaft und ein potenzielles Sicherheitsrisiko für Benutzer, die sich des (nicht intuitiven) Verhaltens nicht bewusst sind, wenn man bedenkt, dass das Verhalten "Letzter gewinnt" von anderen Befehlen stammt.

Ich schlage eine weitere Problemumgehung vor, bei der mehrstufige Builds verwendet werden.
Es kopiert alle Dateien vom Originalbild in das neue Bild, jedoch ohne Metadaten.

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

Ich wollte das Docker-Volume ignorieren, auf das PGDATA damit ich seinen Inhalt mit dem Image und nicht als Volume bündeln kann.
Eine leichtere Lösung für mich bestand darin, einfach den Wert von PGDATA ändern:

FROM postgres:11.2-alpine
ENV PGDATA /var/lib/postgresql/test-data

# stuff that will create all my schemas
COPY create-scripts /docker-entrypoint-initdb.d/

# a weird way to trigger the entrypoint script to run the stuff in docker-entrypoint-initdb.d but not hang after starting postgres
RUN /docker-entrypoint.sh postgres --version

Hat es überhaupt einen Vorteil, EXPOSE und VOLUME in Dockerfiles zu haben? Schließlich können Sie sie einfach in docker run (und in docker-compose Dateien), mit --expose (oder -p ) und benannten Volumes oder Bind-Mounts definieren. Ich wurde mehr als einmal wegen ihnen gebissen und es gibt keine Möglichkeit, sie zurückzusetzen (das Erstellen einer neuen Dockerdatei ist nicht sehr praktikabel, insbesondere wenn offizielle Images oder mit Makefiles erstellte Images erweitert werden). Ich sehe sie als Anti-Muster und denke, es wäre besser, sie abzulehnen .

@lucasbasquerotto EXPOSE wird von Tools wie dem gitlab-runner verwendet, um zu erkennen, ob vom Image als exponiert deklarierte Ports tatsächlich geöffnet sind oder nicht. Ich stimme zu, dass dies eher eine HEALTHCHECK-Pflicht sein sollte, um zu erkennen, ob der Container bereit ist oder nicht, aber eine Liste der deklarierten Ports kann für die Automatisierung in der Tat nützlich sein.
VOLUME wird benötigt, um ein benutzerfreundliches Erlebnis beim Stoppen/Starten eines Containers zu bieten und die Daten automatisch persistieren zu lassen. Auch hier denke ich, dass dies auf andere Weise ausgearbeitet werden kann, aber es ist gut für die Werkzeuge (und in diesem Fall auch für den Menschen), die Daten inspizierbar zu haben.

ps verteidigt die Dockerfile-Syntax nicht, ich weise nur darauf hin, dass die Anti-Muster nicht durch die Schlüsselwörter selbst verursacht werden, sondern weil das Ökosystem nicht voranschreitet, um Probleme zu lösen, die in einem allgemeinen Anwendungsfall wie diesem auftreten können, oder B. ein Image mit einem deklarierten Volume und einigen Startdaten im Volume bereitstellen (z. B. ein MySQL-Image mit vorinstalliertem Schema)

@zarelit Ich weiß nicht genau, wie gitlab-runner funktioniert, aber ich denke, es sollte eine Möglichkeit geben, die zu überprüfenden Ports außerhalb des Dockerfiles anzugeben (ich habe ein Problem gefunden, das wahrscheinlich darauf zurückzuführen ist, weil MySQL exponiert) 2 Ports, aber es sollte nur der Port 3306 überprüft werden: https://gitlab.com/gitlab-org/gitlab-runner/issues/4143). Von dem, was ich sehe, verwendet es auch nur den exponierten Port des letzten Dockerfiles.

Über VOLUME können Sie zustandsbehaftete Daten mit benannten Volumes beibehalten oder mit -v in ein vorhandenes Verzeichnis einhängen (wenn Sie Daten beim Neuerstellen eines Containers beibehalten möchten). Ich denke auch , es wäre besser, diesen Ansatz zu verwenden , da die VOLUME Art obskure innerhalb des dockerfile für

Es erlaubt Ihnen auch nicht, Dateien während des Builds in dieses Verzeichnis zu verschieben (vorausgesetzt, Sie möchten es nicht als Volume verwenden, aber es erbt eine Dockerfile, die das Verzeichnis als Volume definiert, wie WordPress , das /var/www/html/ als VOLUME, und ich musste einige Hacks verwenden, um ein anderes Verzeichnis zu verwenden).

Mit -v erklären Sie explizit, dass Sie das Volumen wollen und vermeiden unerwünschte Überraschungen durch die schwarze Magie von VOLUME im Dockerfile.

Außerdem können viele anonyme Volumes erstellt werden:

Das Definieren eines Volumes im Image weist Docker an, diese Daten getrennt vom Rest des Containers zu speichern, auch wenn Sie das Volume beim Hochfahren des Containers nicht definieren. Docker speichert diese Daten, indem ein lokales Volume ohne Namen erstellt wird. Der Name selbst ist ein langer eindeutiger ID-String, der keinen Verweis auf das Image oder den Container enthält, an den er angehängt ist. Und es sei denn, Sie weisen Docker ausdrücklich an, Volumes zu entfernen, wenn Sie den Container entfernen, bleiben diese Volumes erhalten und werden wahrscheinlich nie wieder verwendet

Quelle: https://boxboat.com/2017/01/23/volumes-and-dockerfiles-dont-mix/

@lucasbasquerotto Ich stimme Ihnen größtenteils zu, es gibt alle seit langem bestehenden Probleme. Ich denke, eine Einstellung sollte einem Weg folgen, auf dem sie nicht ungültig werden, sondern informativ werden wie ... vorgeschlagene Pfade, die Sie in einem Band

Ich denke, dass der gute Teil der Docker-Reise jetzt in den OCI-Standard extrahiert wurde und wir daher neue Tools schreiben sollten, die dieses ganze Erbe nicht auf der Schulter haben.

Für alle, die es nützlich finden, können Sie die Docker-Bilder von tugboat.qa verwenden . Sie sind Erweiterungen mehrerer offizieller Docker-Images, bei denen Volumes entfernt wurden. Minimal dokumentiertes GitHub-Repository hier, wo die schwere Arbeit erledigt wird: https://github.com/TugboatQA/images

Hat es überhaupt einen Vorteil, EXPOSE und VOLUME in Dockerfiles zu haben? Schließlich können Sie sie einfach in docker run (und in docker-compose Dateien), mit --expose (oder -p ) und benannten Volumes oder Bind-Mounts definieren. Ich wurde mehr als einmal wegen ihnen gebissen und es gibt keine Möglichkeit, sie zurückzusetzen (das Erstellen einer neuen Dockerdatei ist nicht sehr praktikabel, insbesondere wenn offizielle Images oder mit Makefiles erstellte Images erweitert werden). Ich sehe sie als Anti-Muster und denke, es wäre besser, sie abzulehnen .

Viele Anbieter stellen ihre Apps heutzutage als einfaches Container-Image bereit und stellen damit Dockerfiles zur Verfügung.
EXPOSE und VOLUME in diesen Dateien zu haben, ermöglicht die Verwendung einfacher Anwendungen mit einem einfachen docker run im App-Verzeichnis. Sie müssen nicht wissen, welche Parameter die App erwartet, sie funktioniert mit allen Standardeinstellungen, die in der Dockerdatei bereitgestellt werden.
Also ja: Während wir bessere, größere Waffen wie Compose oder K8s für komplexe Anwendungen haben, für einfache, lokale Anwendungen sind Dockerfiles immer noch gut geeignet. Und mit Standardeinstellungen, die einfach funktionieren, ist die Verwendung bequem.

@ m451 Ein kürzerer Docker-Lauf ist möglicherweise vorzuziehen als ein längerer (mit mehr definierten Optionen), aber ich halte dies für kein gutes Argument, um Ports und Volumes in der Dockerdatei verfügbar zu machen.

Anstelle von docker run some_image Sie einfach docker run --expose 3000 -v my_volume:/container/dir some_image ausführen und haben ein klares Verständnis der Ports, die dem Host und den Volumes ausgesetzt sind, die auch nach der Zerstörung des Containers bestehen bleiben.

Außerdem ist dies eine triviale Angelegenheit , und Sie legen Volumes nur dann offen und ordnen sie zu, wenn Sie es müssen (vielleicht benötigen Sie nicht alle Ports, die in der Dockerdatei verfügbar gemacht werden, noch alle Volumes definiert. Wenn es wirklich wichtig ist, einige Ports freizugeben? oder ein Volume verwenden, es ist besser, es im Repository zu dokumentieren, damit die Leute nicht nur wissen, was exponiert oder zugeordnet werden muss, sondern warum, schließlich wirkt sich dies auf die Außenseite des Containers aus und kann danach bestehen bleiben der Behälter wird zerstört).

Wenn es sich in der Docker-Datei befindet, kann es tatsächlich schwieriger sein, zu erkennen, was passiert, und auf lange Sicht unerwartete Überraschungen verursachen, wenn ein Volume beibehalten wird und Sie es nicht wissen (insbesondere, wenn eine Docker-Datei von einem anderen geerbt wird, wissen Sie es möglicherweise nicht vorher, dass ein Volumen definiert ist, es sei denn, Sie untersuchen genauer, was es tut). Daher würde ich VOLUME und EXPOSE als schlecht ansehen, selbst wenn dieses Problem gelöst ist.

Außerdem ist dieses Problem zwar nicht gelöst (und ich habe keine Ahnung, wie viele Jahre es dauern wird, es zu lösen, wenn man bedenkt, dass es seit mehr als fünfeinhalb Jahren geöffnet ist), aber ich habe einfach KEINE MÖGLICHKEIT, es zurückzusetzen sie .

Hat es überhaupt einen Vorteil, EXPOSE und VOLUME in Dockerfiles zu haben? Schließlich können Sie sie einfach in docker run (und in docker-compose Dateien), mit --expose (oder -p ) und benannten Volumes oder Bind-Mounts definieren. Ich wurde mehr als einmal wegen ihnen gebissen und es gibt keine Möglichkeit, sie zurückzusetzen (das Erstellen einer neuen Dockerdatei ist nicht sehr praktikabel, insbesondere wenn offizielle Images oder mit Makefiles erstellte Images erweitert werden). Ich sehe sie als Anti-Muster und denke, es wäre besser, sie abzulehnen .

Viele Anbieter stellen ihre Apps heutzutage als einfaches Container-Image bereit und stellen damit Dockerfiles zur Verfügung.
EXPOSE und VOLUME in diesen Dateien zu haben, ermöglicht die Verwendung einfacher Anwendungen mit einem einfachen docker run im App-Verzeichnis. Sie müssen nicht wissen, welche Parameter die App erwartet, sie funktioniert mit allen Standardeinstellungen, die in der Dockerdatei bereitgestellt werden.
Also ja: Während wir bessere, größere Waffen wie Compose oder K8s für komplexe Anwendungen haben, für einfache, lokale Anwendungen sind Dockerfiles immer noch gut geeignet. Und mit Standardeinstellungen, die einfach funktionieren, ist die Verwendung bequem.

Ich würde argumentieren, dass Anbieter, die das tun, es aus Unwissenheit tun. Nicht verstehen, welche Probleme dies für Leute verursacht, die ihr Produkt in einer Produktionsumgebung verwenden möchten. Sicher, es macht es für jemanden einfacher, eine Test-/Demo-Instanz des Produkts einzurichten. Aber jetzt, wenn ich es wirklich ausführen möchte, muss ich ihr Dockerfile git clone/sed oder mein eigenes erstellen, nur um ein funktionierendes Image zu erhalten.

@ m451 Ein kürzerer Docker-Lauf ist möglicherweise vorzuziehen als ein längerer (mit mehr definierten Optionen), aber ich halte dies für kein gutes Argument, um Ports und Volumes in der Dockerdatei verfügbar zu machen.

Anstelle von docker run some_image Sie einfach docker run --expose 3000 -v my_volume:/container/dir some_image ausführen und haben ein klares Verständnis der Ports, die dem Host und den Volumes ausgesetzt sind, die auch nach der Zerstörung des Containers bestehen bleiben.

Außerdem ist dies eine triviale Angelegenheit , und Sie legen Volumes nur dann offen und ordnen sie zu, wenn Sie es müssen (vielleicht benötigen Sie nicht alle Ports, die in der Dockerdatei verfügbar gemacht werden, noch alle Volumes definiert. Wenn es wirklich wichtig ist, einige Ports freizugeben? oder ein Volume verwenden, es ist besser, es im Repository zu dokumentieren, damit die Leute nicht nur wissen, was exponiert oder zugeordnet werden muss, sondern warum, schließlich wirkt sich dies auf die Außenseite des Containers aus und kann danach bestehen bleiben der Behälter wird zerstört).

Wenn es sich in der Dockerdatei befindet, kann es tatsächlich schwieriger sein, zu erkennen, was passiert, und auf lange Sicht unerwartete Überraschungen verursachen, wenn ein Volume beibehalten wird und Sie es nicht wissen (insbesondere, wenn ein Dockerfile von einem anderen geerbt wird, wissen Sie es möglicherweise nicht vorher, dass ein Volumen definiert ist, es sei denn, Sie untersuchen genauer, was es tut). Daher würde ich VOLUME und EXPOSE als schlecht ansehen, selbst wenn dieses Problem gelöst ist.

Außerdem ist dieses Problem zwar nicht gelöst (und ich habe keine Ahnung, wie viele Jahre es dauern wird, es zu lösen, wenn man bedenkt, dass es seit mehr als fünfeinhalb Jahren geöffnet ist), aber ich habe einfach KEINE MÖGLICHKEIT, es zurückzusetzen sie .

Einverstanden. Lassen Sie uns also eine Standardmethode definieren, um zu kommunizieren, welche Parameter erforderlich sind.
Wenn keine vorhanden ist, haben wir am Ende das gleiche Durcheinander wie bei älteren Apps: herstellerspezifische Dokumente und Dokumentationsformate. Einige sagen Ihnen, welche Ports Sie öffnen müssen, andere nicht. Manche sagen Ihnen nur die Hälfte, manche sagen Ihnen die falschen Ports. Manche sagen Ihnen nur die Portnummer, aber nicht das Protokoll und so weiter.

Dockerfiles waren eine großartige Möglichkeit, dieses Durcheinander zu standardisieren.

@ m451 Ich stimme Ihnen darin zu, aber es ist gut zu bedenken, dass das

Wenn Sie Daten dauerhaft speichern möchten, möchten Sie, dass sie auf einem benannten Volume oder an einem Ort auf dem Host bereitgestellt werden, VOLUME hilft dabei nicht. Wenn temporäre Daten performanter gespeichert werden sollen, hilft VOLUME (nur in diesem Fall kann VOLUME hilfreich sein). Das Schreiben in den Container ist langsamer, weil es die Copy-on-Write- Strategie verwendet. Aber auch hier vermeidet das Zuordnen des Volumens beim Docker-Lauf CoW (Sie brauchen kein VOLUME), der einzige Nachteil ist, dass Ihre Anweisung länger ist und Sie den Pfad kennen müssen (dies ist jedoch nur der Fall, wenn Sie eine beeinträchtigte Leistung haben zu CoW).

Die Verwendung von VOLUME und EXPOSE als Dokumentationstyp rechtfertigt keine schlechte (oder fehlende) Dokumentation . Und es kann (und wird wahrscheinlich) auch einigen Verbrauchern des Images schaden.

@ m451 Ich stimme Ihnen darin zu, aber es ist gut zu bedenken, dass das

Richtig. Die ganze Idee von Ports aus einer Sekunde. Perspektive ist veraltet. Aber: Hier versuchen wir zu definieren, welche Ports geöffnet werden müssen und welche Ports geschlossen bleiben können und zu verstehen, welche Daten über jeden Port ausgetauscht werden. HTTPS ist heute zu einem Wrapper für so ziemlich alles geworden und außer dem Autor des Codes gibt es normalerweise niemanden, der genau weiß, welche Daten über einen bestimmten Port übertragen werden. Und selbst dann kann es sich mit jedem Update ändern.

In RL ist es egal, welche Daten / Informationen über welchen Port transportiert werden, außer dass Sie die Anwendung beheben müssen. Sie entscheiden sich, der Anwendung zu vertrauen. Wenn die Anwendung also Port X und Y öffnet, vertrauen Sie ihr auch das.
Für den täglichen Standardbetrieb ist es gut, einfach eine App zu starten und sie funktioniert sofort (sichere Standardeinstellungen werden vorausgesetzt).
Container sind zu einer Form von Verpackungs-Apps geworden, damit sie sofort einsatzbereit sind.

Trotzdem stimme ich zu, dass gute Dokumente wichtig sind. Doch in RL möchte niemand stundenlang Dokumente lesen, nur um zu wissen, welche Ports geöffnet werden müssen. Es bringt keinen Vorteil für die täglichen Betriebsaufgaben.

Mein Stück vom Kuchen.

Die Verwendung von VOLUME im Dockerfile ist wertlos . Wenn ein Benutzer Persistenz benötigt, stellt er sicher, dass er beim Ausführen des angegebenen Containers eine Volumezuordnung bereitstellt. Es war sehr schwer herauszufinden, dass mein Problem, den Besitz eines Verzeichnisses (/var/lib/influxdb) nicht festlegen zu können, auf die VOLUME-Deklaration in der Dockerfile von InfluxDB zurückzuführen war. Ohne eine Option vom Typ vollständig loszuwerden , kann ich _alles_, das sich auf den angegebenen Ordner bezieht, nicht ändern. Dies ist nicht ideal, insbesondere wenn Sie sicherheitsbewusst sind und eine bestimmte UID angeben möchten, sollte das Image als ausgeführt werden , um zu vermeiden, dass ein zufälliger Benutzer mit mehr Berechtigungen als nötig Software auf Ihrem Host ausführt.

Es sollte eine Möglichkeit geben, diese VOLUME-Anweisungen zu überschreiben, wenn Bilder für die Benutzeranpassung erweitert werden. Meine einzige Lösung besteht im Moment darin, das Image selbst vollständig neu zu erstellen, wodurch die gesamte _Dockerfile FROM_-Dynamik nutzlos wird.

VON nginx:neueste
Nach der Bereitstellung in Heroku wurde der 80-Port von nginx freigegeben, aber das wird von Heroku nicht zugelassen. Was kann ich also tun? Kopieren Sie alle Dockerfiles von nginx und entfernen Sie die EXPOSE 80?

Ich werde keine neuen schreiben... aber es wäre sehr nett, die EXPOSE-Direktive zu überschreiben.

Teilen Sie dies - https://github.com/gdraheim/docker-copyedit/blob/master/docker-copyedit.py (nicht meine Kreation, um das klar zu sagen, danke @gdraheim!)

Dies half mir beim Entfernen eines Volumes aus einem Postgres-Container, der in der Dockerfile mit dem Befehl festgelegt wurde:

python docker-copyedit.py FROM postgres:11.5-alpine INTO postgres:11.5-alpine remove volume /var/lib/postgresql/data

Scheint den Job ohne Beschädigung des Containers erledigt zu haben, das Original-Image genommen, angepasst, ein neues Image ohne das Volume erstellt (gemäß dem docker inspect Lauf auf einem Container, der aus dem angepassten Image erstellt wurde), nicht habe es für alles andere verwendet, aber die git README ermöglicht eine Vielzahl von Operationen, z

 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     REMOVE PORT 4444
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove port ldap and rm port ldaps
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove all ports
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     add port ldap and add port ldaps

LABEL ist eine weitere "Eigenschaft" (noch nicht erwähnt), die die Fähigkeit zum "Unscharfschalten" verwenden könnte.

Wie in diesem SO-Post erwähnt: https://stackoverflow.com/questions/50978051/how-do-i-unset-a-docker-image-label

Ein weiterer Anwendungsfall zum Zurücksetzen / Entfernen von VOLUME aus Upstream-Images:

Ich arbeite daran, ein Oracle-Datenbank-Image zu erweitern, aber es hat ein Volumen auf /opt/oracle/oradata . Im Standard-Oracle-Image wird die Datenbank beim Containerstart erstellt und schreibt auf dieses Volume. Dies führt jedoch dazu, dass der Container für den ersten Start 25 Minuten benötigt, was nicht akzeptabel ist. Ich arbeite also an einem Image, bei dem die Datenbank beim Image-Build erstellt wird, aber dafür muss ich die VOLUME /opt/oracle/oradata entfernen, da meine Datenbank erstellt wird, aber wenn ich den Container starte, ist das Dateisystem /opt/oracle/oradata leer erneut und meine Datenbank startet nicht.

Ich arbeite daran, ein Oracle-Datenbank-Image zu erweitern, aber es hat ein Volumen auf /opt/oracle/oradata .

Genau mein Anwendungsfall auch. Ich möchte eine vorab zugewiesene Pluggable-Datenbank generieren, die andere aus unserer privaten Docker-Registrierung ziehen können ... aber das Volume fehlt. Ich muss tiefer graben und mich für den am wenigsten hässlichen Workaround entscheiden.

Ich habe es wie folgt gelöst:

Ich habe docker-copyedit verwendet , um das Volume zu entfernen, dann habe ich ein Bash-Skript geschrieben, um die Datenbank zu erstellen (Sie können sich die Oracle ansehen , um zu sehen, wie es geht). Mit der vorkonfigurierten PDB dauert es jetzt nur noch 25 Sekunden, um einen Container aus dem Image zu starten. Aber das Bild wird richtig groß.

Wäre ein besserer Ansatz, die vorhandene Docker-Spezifikation zu erweitern, um ein Konzept von sticky env-Variablen / Überschreibungsoptionen einzuschließen, wie z.

zB mein Projekt basierend auf dem vorgeschalteten Tomcat-Image:

--ENV CATALINA_HOME /some/other/path
VON Kater:8.5.54-jdk8-openjdk
...

Wo eine ENV mit -- deklariert wird, sollte sie auf einen Sticky-Status angehoben werden und den deklarierten Wert beibehalten / jeden Wert überschreiben, der später in der Verarbeitungskette des Dockerfiles für diese Variable angetroffen wird.

--ENV = ab jetzt im Dockerfile.

Daher könnte dies am Anfang eines Dockerfiles verwendet werden, wenn Sie möchten, dass es Vorrang vor jeder weiteren Begegnung mit derselben Variablen hat, z. B. in mehrstufigen Builds. Würde auch Flexibilität ermöglichen, je nachdem, wo im Dockerfile es platziert wurde, damit Verweise höher in der Datei unabhängig sind.

Dann wäre kein UNVOLUME erforderlich, da der richtige Ansatz darin besteht, VOLUME mit einer ENV-Referenz zu deklarieren, die jemand anderes überschreiben könnte.

z.B

ENV PROJ_VOL /some/path
VOLUMEN $PROJ_VOL

Sieht so aus, als ob ENTRYPOINT [] und ENTRYPOINT [""] beide den Cache bei jedem Build ungültig machen, wenn BuildKit nicht verwendet wird. Einfaches Dockerfile zum Demonstrieren:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT []

RUN echo "HERE!"

Die Schritte 2 und 3 werden _nie_ den Cache verwenden. Das ist mein Workaround:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT ["/usr/bin/env"]

RUN echo "HERE!"

Ich kann einen Cache-Fehler bei Ihrem ersten Muster nicht reproduzieren: :confused:

$ cat Dockerfile
FROM alpine:3.12
ENTRYPOINT []
RUN echo 'HERE!'

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Running in d921be2e563d
Removing intermediate container d921be2e563d
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Running in 9e2ca2cf1f9f
HERE!
Removing intermediate container 9e2ca2cf1f9f
 ---> d398fdd442b1
Successfully built d398fdd442b1

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Using cache
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Using cache
 ---> d398fdd442b1
Successfully built d398fdd442b1

Ich denke, Sie müssen ein Bild verwenden, das ENTRYPOINT . Versuchen Sie es mit dem Bild, das ich gemacht habe, oder mysql .

Oh interessant - ich kann mit mysql:8.0 reproduzieren. Solider Fehler! :+1:

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen