Grundlegendes zur Anweisung "VOLUME" in DockerFile

135

Unten ist der Inhalt meiner "Dockerfile"

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app

# change working dir to /usr/src/app
WORKDIR /usr/src/app

VOLUME . /usr/src/app

RUN npm install

EXPOSE 8080

CMD ["node" , "server" ]

In dieser Datei erwarte ich, dass die Anweisung "VOLUME. / Usr / src / app" den Inhalt des aktuellen Arbeitsverzeichnisses im Host bereitstellt, der im Ordner / usr / src / app des Containers bereitgestellt werden soll.

Bitte lassen Sie mich wissen, ob dies der richtige Weg ist.

Refactor
quelle

Antworten:

88

Das offizielle Docker-Tutorial sagt:

Ein Datenvolumen ist ein speziell festgelegtes Verzeichnis in einem oder mehreren Containern, das das Union-Dateisystem umgeht. Datenmengen bieten verschiedene nützliche Funktionen für persistente oder gemeinsam genutzte Daten:

  • Volumes werden beim Erstellen eines Containers initialisiert. Wenn das Basis-Image des Containers Daten am angegebenen Einhängepunkt enthält, werden
    diese vorhandenen Daten bei der Volume-
    Initialisierung in das neue Volume kopiert . (Beachten Sie, dass dies beim Mounten eines Hostverzeichnisses nicht gilt
    .)
  • Datenmengen können von Containern gemeinsam genutzt und wiederverwendet werden.

  • Änderungen an einem Datenvolumen werden direkt vorgenommen.

  • Änderungen an einem Datenvolumen werden beim Aktualisieren eines Bildes nicht berücksichtigt.

  • Datenmengen bleiben auch dann bestehen, wenn der Container selbst gelöscht wird.

In können DockerfileSie nur das Ziel eines Volumes in einem Container angeben . zB /usr/src/app.

Wenn Sie beispielsweise einen Container ausführen docker run --volume=/opt:/usr/src/app my_image, müssen Sie möglicherweise dessen Einhängepunkt ( / opt ) auf dem Hostcomputer angeben, müssen dies jedoch nicht . Wenn Sie kein --volumeArgument angeben , wird der Einhängepunkt automatisch ausgewählt, normalerweise unter /var/lib/docker/volumes/.

Bucharow Sergey
quelle
274

Kurzum: Nein, Ihre VOLUMEAnweisung ist nicht korrekt.

Docker-Dateien VOLUMEgeben ein oder mehrere Volumes an, wenn container-seitige Pfade angegeben sind. Der Bildautor kann jedoch keinen Hostpfad angeben. Auf der Hostseite werden die Volumes mit einem sehr langen ID-ähnlichen Namen im Docker-Stammverzeichnis erstellt. Auf meiner Maschine ist das /var/lib/docker/volumes.

Hinweis: Da der automatisch generierte Name extrem lang ist und aus menschlicher Sicht keinen Sinn ergibt, werden diese Bände häufig als "unbenannt" oder "anonym" bezeichnet.

Ihr Beispiel, das ein '.' Das Zeichen wird nicht einmal auf meinem Computer ausgeführt, egal ob ich den Punkt zum ersten oder zweiten Argument mache. Ich erhalte diese Fehlermeldung:

Docker: Fehlerantwort vom Daemon: oci Laufzeitfehler: container_linux.go: 265: Start des Containerprozesses verursacht "process_linux.go: 368: container init verursacht" open / dev / ptmx: keine solche Datei oder kein solches Verzeichnis ".

Ich weiß , dass nicht sehr wertvoll ist wohl jemand zu diesem Punkt gesagt , was hat versucht , zu verstehen , VOLUMEund -vund es bietet sicherlich keine Lösung für das, was Sie versuchen zu erreichen. Hoffentlich werden die folgenden Beispiele mehr Licht in diese Fragen bringen.

Minitutorial: Festlegen von Volumes

Angesichts dieser Docker-Datei:

FROM openjdk:8u131-jdk-alpine
VOLUME vol1 vol2

(Für das Ergebnis dieses Minitutoriums spielt es keine Rolle, ob wir angeben vol1 vol2oder /vol1 /vol2- fragen Sie mich nicht warum)

Baue es:

docker build -t my-openjdk

Lauf:

docker run --rm -it my-openjdk

Führen Sie lsim Container die Befehlszeile aus, und Sie werden feststellen, dass zwei Verzeichnisse vorhanden sind. /vol1und /vol2.

Durch Ausführen des Containers werden auch zwei Verzeichnisse oder "Volumes" auf der Hostseite erstellt.

Wenn der Container ausgeführt wird, führen Sie ihn docker volume lsauf dem Host-Computer aus, und Sie werden Folgendes sehen (der Kürze halber habe ich den mittleren Teil des Namens durch drei Punkte ersetzt):

DRIVER    VOLUME NAME
local     c984...e4fc
local     f670...49f0

Zurück im Container ausführen touch /vol1/weird-ass-file(erstellt eine leere Datei an dieser Stelle).

Diese Datei ist jetzt auf dem Host-Computer in einem der unbenannten Volumes verfügbar. Lol. Ich habe zwei Versuche gebraucht, weil ich zuerst das erste aufgelistete Volume ausprobiert habe, aber schließlich habe ich meine Datei mit dem folgenden Befehl auf dem Host-Computer im zweiten aufgelisteten Volume gefunden:

sudo ls /var/lib/docker/volumes/f670...49f0/_data

Ebenso können Sie versuchen, diese Datei auf dem Host zu löschen, und sie wird auch im Container gelöscht.

Hinweis: Der _dataOrdner wird auch als "Einhängepunkt" bezeichnet.

Beenden Sie den Container und listen Sie die Volumes auf dem Host auf. Sie sind weg. Wir haben das --rmFlag beim Ausführen des Containers verwendet und diese Option löscht nicht nur den Container beim Beenden, sondern auch die Volumes.

Führen Sie einen neuen Container aus, geben Sie jedoch ein Volume an, indem Sie -v:

docker run --rm -it -v /vol3 my-openjdk

Dies fügt ein drittes Volume hinzu und das gesamte System verfügt über drei unbenannte Volumes. Der Befehl wäre abgestürzt, wenn wir nur angegeben hätten -v vol3. Das Argument muss ein absoluter Pfad innerhalb des Containers sein. Auf der Hostseite ist das neue dritte Volume anonym und befindet sich zusammen mit den beiden anderen Volumes in /var/lib/docker/volumes/.

Es wurde bereits erwähnt, dass das Dockerfilenicht einem Hostpfad zugeordnet werden kann, was für uns ein Problem darstellt, wenn wir versuchen, zur Laufzeit Dateien vom Host in den Container zu bringen. Eine andere -vSyntax löst dieses Problem.

Stellen Sie sich vor, ich habe einen Unterordner in meinem Projektverzeichnis ./src, mit dem ich /srcim Container synchronisieren möchte . Dieser Befehl macht den Trick:

docker run -it -v $(pwd)/src:/src my-openjdk

Beide Seiten des :Charakters erwarten einen absoluten Pfad. Die linke Seite ist ein absoluter Pfad auf dem Host-Computer, die rechte Seite ist ein absoluter Pfad innerhalb des Containers. pwdist ein Befehl, der "aktuelles / Arbeitsverzeichnis drucken". Wenn Sie den Befehl $()eingeben, wird der Befehl in Klammern gesetzt, in einer Unterschale ausgeführt und der absolute Pfad zu unserem Projektverzeichnis zurückgegeben.

Nehmen wir an, wir haben alles ./src/Hello.javain unserem Projektordner auf dem Host-Computer mit den folgenden Inhalten:

public class Hello {
    public static void main(String... ignored) {
        System.out.println("Hello, World!");
    }
}

Wir erstellen diese Docker-Datei:

FROM openjdk:8u131-jdk-alpine
WORKDIR /src
ENTRYPOINT javac Hello.java && java Hello

Wir führen diesen Befehl aus:

docker run -v $(pwd)/src:/src my-openjdk

Dies druckt "Hallo Welt!".

Das Beste daran ist, dass wir die Java-Datei bei einem zweiten Durchlauf mit einer neuen Nachricht für eine andere Ausgabe ändern können - ohne das Bild neu erstellen zu müssen =)

Schlussbemerkungen

Ich bin ziemlich neu in Docker und das oben erwähnte "Tutorial" spiegelt Informationen wider, die ich aus einem dreitägigen Kommandozeilen-Hackathon gesammelt habe. Ich schäme mich fast, dass ich keine Links zu klaren englischsprachigen Dokumentationen bereitstellen konnte, die meine Aussagen stützen, aber ich denke ehrlich, dass dies auf mangelnde Dokumentation und nicht auf persönlichen Aufwand zurückzuführen ist. Ich weiß, dass die Beispiele mit meinem aktuellen Setup "Windows 10 -> Vagrant 2.0.0 -> Docker 17.09.0-ce" wie angekündigt funktionieren.

Das Tutorial löst nicht das Problem "Wie geben wir den Pfad des Containers in der Docker-Datei an und lassen den Befehl run nur den Hostpfad angeben". Es könnte einen Weg geben, ich habe ihn einfach nicht gefunden.

Schließlich habe ich das Gefühl, dass die Angabe VOLUMEin der Docker-Datei nicht nur ungewöhnlich ist, sondern wahrscheinlich eine bewährte Methode ist, die niemals verwendet wird VOLUME. Aus zwei Gründen. Der erste Grund, den wir bereits identifiziert haben: Wir können den Hostpfad nicht angeben - was gut ist, da Dockerfiles sehr unabhängig von den Besonderheiten eines Hostcomputers sein sollten. Der zweite Grund ist jedoch, dass die Benutzer möglicherweise vergessen, die --rmOption beim Ausführen des Containers zu verwenden. Man könnte daran denken, den Behälter zu entfernen, aber vergessen, das Volumen zu entfernen. Selbst mit dem besten menschlichen Gedächtnis kann es eine entmutigende Aufgabe sein, herauszufinden, welche aller anonymen Volumes sicher entfernt werden können.

Martin Andersson
quelle
2
Wann sollten wir unbenannte / anonyme Volumes verwenden?
Searene
10
@ Martin, vielen Dank. Ihr Hackathon und das daraus resultierende Tutorial hier werden sehr geschätzt.
Beezer
6
"Ich konnte keine Links zu einer klaren englischsprachigen Dokumentation bereitstellen ... Ich glaube ehrlich, dass dies auf einen Mangel an Dokumentation zurückzuführen ist." Ich kann bestätigen. Dies ist die gründlichste und aktuellste Dokumentation, die ich gefunden habe und nach der ich stundenlang gesucht habe.
user697576
4
docker volume prunekann verwendet werden, um übrig gebliebene Volumes zu bereinigen, die nicht an laufende Container angehängt sind. Um nicht zu sagen, dass es einfach sein wird, potenziell wichtige durch ID allein zu unterscheiden ...
Jeremy
4
"Für das Ergebnis dieses Minitutors spielt es keine Rolle, ob wir vol1 vol2 oder / vol1 / vol2 angeben - fragen Sie mich nicht warum." @MartinAndersson das ist , weil das aktuelle Arbeitsverzeichnis ist /, so vol1ist in Bezug auf /, die Entschlüsse zu /vol1. Wenn Sie WORKDIRein Arbeitsverzeichnis mit Ausnahme angeben /, vol1und /vol1würde nicht mehr in das gleiche Verzeichnis verweisen.
Sebastian
41

Wenn Sie eine VOLUMEZeile in einer Docker-Datei angeben, werden einige Metadaten in Ihrem Bild konfiguriert. Es ist jedoch wichtig, wie diese Metadaten verwendet werden.

Was haben diese beiden Zeilen getan:

WORKDIR /usr/src/app
VOLUME . /usr/src/app

Die WORKDIRZeile dort erstellt das Verzeichnis, falls es nicht vorhanden ist, und aktualisiert einige Bildmetadaten, um alle relativen Pfade anzugeben, zusammen mit dem aktuellen Verzeichnis für Befehle, RUNdie sich an diesem Speicherort befinden. Die VOLUMEZeile dort gibt zwei Volumes an , eines ist der relative Pfad .und das andere ist /usr/src/app, dass beide zufällig dasselbe Verzeichnis sind. Meistens VOLUMEenthält die Zeile nur ein einziges Verzeichnis, aber es kann mehrere enthalten, wie Sie es getan haben, oder es kann ein json-formatiertes Array sein.

Sie können keine Volume-Quelle in der Docker-Datei angeben : Eine häufige Verwirrung beim Angeben von Volumes in einer Docker-Datei besteht darin, dass versucht wird, die Laufzeitsyntax einer Quelle und eines Ziels zur Image-Erstellungszeit abzugleichen. Dies funktioniert nicht . Die Docker-Datei kann nur das Ziel des Volumes angeben. Es wäre ein trivialer Sicherheits-Exploit, wenn jemand die Quelle eines Volumes definieren könnte, da er ein allgemeines Image auf dem Docker-Hub aktualisieren könnte, um das Stammverzeichnis in den Container einzubinden und dann einen Hintergrundprozess innerhalb des Containers als Teil eines Einstiegspunkts zu starten Fügt Anmeldungen zu / etc / passwd hinzu, konfiguriert systemd so, dass beim nächsten Neustart ein Bitcoin Miner gestartet wird, oder durchsucht das Dateisystem nach Kreditkarten, SSNs und privaten Schlüsseln, die an einen Remote-Standort gesendet werden sollen.

Was macht die VOLUME-Linie? Wie bereits erwähnt, werden einige Bildmetadaten so festgelegt, dass ein Verzeichnis im Bild ein Volume ist. Wie werden diese Metadaten verwendet? Jedes Mal, wenn Sie einen Container aus diesem Image erstellen, erzwingt Docker, dass dieses Verzeichnis ein Volume ist. Wenn Sie in Ihrem Ausführungsbefehl kein Volume angeben oder keine Datei erstellen, besteht die einzige Option für Docker darin, ein anonymes Volume zu erstellen. Dies ist ein lokal benanntes Volume mit einer langen eindeutigen ID für den Namen und keinem anderen Hinweis darauf, warum es erstellt wurde oder welche Daten es enthält (anonyme Volumes sind Daten, bei denen Daten verloren gehen). Wenn Sie das Volume überschreiben und auf ein benanntes oder Host-Volume verweisen, werden Ihre Daten stattdessen dorthin verschoben.

VOLUME bricht Dinge ab: Sie können ein Volume, das einmal in einer Docker-Datei definiert wurde, nicht deaktivieren. Und was noch wichtiger ist, der RUNBefehl im Docker wird mit temporären Containern implementiert. Diese temporären Container erhalten ein temporäres anonymes Volume. Dieses anonyme Volume wird mit dem Inhalt Ihres Bildes initialisiert. Alle Schreibvorgänge innerhalb des Containers von Ihrem RUNBefehl werden auf dieses Volume ausgeführt. Wenn der RUNBefehl beendet ist, werden Änderungen am Image gespeichert und Änderungen am anonymen Volume werden verworfen. Aus diesem Grund empfehle ich dringend, keine VOLUMEinnerhalb der Docker-Datei zu definieren. Dies führt zu unerwartetem Verhalten für nachgeschaltete Benutzer Ihres Images, die das Image mit Anfangsdaten am Volume-Speicherort erweitern möchten.

Wie sollten Sie ein Volume angeben? Geben Sie a an, um anzugeben, wo Sie Volumes in Ihr Image aufnehmen möchten docker-compose.yml. Benutzer können dies ändern, um den Speicherort des Volumes an ihre lokale Umgebung anzupassen, und es werden andere Laufzeiteinstellungen wie Veröffentlichungsports und Netzwerke erfasst.

Jemand sollte das dokumentieren! Sie haben. Docker enthält Warnungen zur Verwendung von VOLUME in der Dokumentation zur Docker- Datei sowie Hinweise zur Angabe der Quelle zur Laufzeit:

  • Ändern des Volumes innerhalb der Docker-Datei: Wenn Build-Schritte die Daten innerhalb des Volumes ändern, nachdem sie deklariert wurden, werden diese Änderungen verworfen.

...

  • Das Host-Verzeichnis wird zur Container-Laufzeit deklariert: Das Host-Verzeichnis (der Mountpoint) ist von Natur aus hostabhängig. Dies dient der Wahrung der Image-Portabilität, da nicht garantiert werden kann, dass ein bestimmtes Host-Verzeichnis auf allen Hosts verfügbar ist. Aus diesem Grund können Sie kein Hostverzeichnis in der Docker-Datei bereitstellen. Die VOLUME Anweisung unterstützt die Angabe eines host-dirParameters nicht. Sie müssen den Mountpunkt angeben, wenn Sie den Container erstellen oder ausführen.
BMitch
quelle
36

Der VOLUMEBefehl in a Dockerfileist ziemlich legitim, völlig konventionell, absolut in Ordnung zu verwenden und wird in ohnehin nicht veraltet. Ich muss es nur verstehen.

Wir verwenden es, um auf Verzeichnisse zu verweisen, in die die App im Container viel schreibt. Wir verwenden nicht VOLUMEnur, weil wir wie eine Konfigurationsdatei zwischen Host und Container teilen möchten.

Der Befehl benötigt lediglich einen Parameter. Ein Pfad zu einem Ordner WORKDIRinnerhalb des Containers. Dann erstellt Docker ein Volume in seinem Diagramm (/ var / lib / docker) und hängt es in den Ordner im Container ein. Jetzt kann der Container mit hoher Leistung irgendwo schreiben. Ohne den VOLUMEBefehl ist die Schreibgeschwindigkeit in den angegebenen Ordner sehr langsam, da der Container jetzt seine copy on writeStrategie im Container selbst verwendet. Die copy on writeStrategie ist ein Hauptgrund, warum Volumina existieren.

Wenn Sie über den durch den VOLUMEBefehl angegebenen Ordner mounten , wird der Befehl nie ausgeführt, da er VOLUMEnur ausgeführt wird, wenn der Container gestartet wird ENV.

Grundsätzlich erhalten Sie mit VOLUMEBefehl Leistung, ohne extern Volumes bereitzustellen. Daten werden auch über Containerläufe hinweg ohne externe Bereitstellungen gespeichert. Wenn Sie fertig sind, montieren Sie einfach etwas darüber.

Einige gute Anwendungsbeispiele:
- Protokolle
- temporäre Ordner

Einige schlechte Anwendungsfälle:
- statische Dateien
- Konfigurationen
- Code

Herr Hafen
quelle
2
In Bezug auf die Anwendungsfälle für gute und schlechte Beispiele heißt es auf der Docker-Seite "Dockerfile Best Practices" : "Es wird dringend empfohlen , VOLUME für veränderbare und / oder vom Benutzer zu wartende Teile Ihres Bildes zu verwenden." Ich denke, es gibt Konfigurationen.
OmerSch
2
Es ist in Ordnung, die VOLUMEVerzeichnisse für Konfigurationen explizit anzugeben. Sobald Sie jedoch eine Konfiguration tatsächlich gemountet haben, müssen Sie über dieses Verzeichnis mounten, und daher wird der VOLUMEBefehl nicht ausgeführt. Daher ist es sinnlos, einen VOLUMEBefehl für ein für eine Konfiguration angegebenes Verzeichnis zu verwenden. Auch das Initialisieren eines Volumendiagramms mit einer einzelnen statischen schreibgeschützten Datei ist ein schwerwiegender Overkill. Ich stehe also zu dem, was ich gesagt habe, und brauche keine VOLUMEBefehle für Konfigurationen.
Herr Hafen
Volumes können aufgrund von Implementierungsdetails unterschiedliche Leistungsmerkmale aufweisen. Datenbankdatendateien passen in diesen Anwendungsfall, aber wozu sollten Daten neben dem (kurzlebigen) Containerspeicher gespeichert werden? Das heißt, die Existenz von Volumina der Leistung zuzuordnen ist falsch.
André Werlang
33

Um die volumeAnweisung in Dockerfile besser zu verstehen , lernen wir die typische Verwendung von Volumes in der offiziellen Docker-Datei-Implementierung von MySQL kennen.

VOLUME /var/lib/mysql

Referenz: https://github.com/docker-library/mysql/blob/3362baccb4352bcf0022014f67c1ec7e6808b8c5/8.0/Dockerfile

Dies /var/lib/mysqlist der Standardspeicherort von MySQL, in dem Datendateien gespeichert werden.

Wenn Sie den Testcontainer nur zu Testzwecken ausführen, dürfen Sie seinen Montagepunkt nicht angeben, z

docker run mysql:8

Dann verwendet die MySQL-Containerinstanz den Standard-Mount-Pfad, der durch die volumeAnweisung in Dockerfile angegeben wird. Die Volumes werden mit einem sehr langen ID-ähnlichen Namen im Docker-Stammverzeichnis erstellt. Dies wird als "unbenanntes" oder "anonymes" Volume bezeichnet. Im Ordner des zugrunde liegenden Hostsystems / var / lib / docker / volume.

/var/lib/docker/volumes/320752e0e70d1590e905b02d484c22689e69adcbd764a69e39b17bc330b984e4

Dies ist sehr praktisch für schnelle Testzwecke, ohne dass der Einhängepunkt angegeben werden muss, kann jedoch die beste Leistung erzielen, wenn Volume für den Datenspeicher und nicht die Containerebene verwendet wird.

Für eine formale Verwendung müssen Sie den Mount-Pfad mithilfe des benannten Volumes oder des Bind-Mount angeben, z

docker run  -v /my/own/datadir:/var/lib/mysql mysql:8

Der Befehl stellt das Verzeichnis / my / own / datadir vom zugrunde liegenden Hostsystem als / var / lib / mysql im Container bereit. Das Datenverzeichnis / my / own / datadir wird nicht automatisch gelöscht, auch wenn der Container gelöscht wird.

Verwendung des offiziellen MySQL-Bildes (Bitte überprüfen Sie den Abschnitt "Speicherort der Daten"):

Referenz: https://hub.docker.com/_/mysql/

Li-Tian
quelle
2
Ihre Erklärung gefällt mir sehr gut.
LukaszTaraszka
Aber Docker speichert die Änderungen trotzdem. Sie können auch den Mount-Pfad festlegen, -vohne das Volume in der Docker-Datei
Alex78191
1

Ich halte die Verwendung von VOLUME auf keinen Fall für gut, es sei denn, Sie erstellen ein Bild für sich selbst und niemand anderes wird es verwenden.

Ich war aufgrund von VOLUME, das in von mir erweiterten Basis-Images verfügbar gemacht wurde, negativ betroffen und erfuhr erst von dem Problem, nachdem das Image bereits ausgeführt wurde, wie z. B. WordPress, das den /var/www/htmlOrdner als VOLUME deklariert , und dies bedeutete, dass alle Dateien während hinzugefügt oder geändert wurden Die Build-Phase wird nicht berücksichtigt, und Live-Änderungen bleiben bestehen, auch wenn Sie es nicht wissen. Es gibt eine hässliche Problemumgehung, um ein Webverzeichnis an einem anderen Ort zu definieren, aber dies ist nur eine schlechte Lösung für ein einfacheres Muss: Entfernen Sie einfach die VOLUME-Direktive.

Mit der -vOption können Sie die Absicht des Volumens auf einfache Weise erreichen. Dies macht nicht nur deutlich, wie groß das Volumen des Containers sein wird (ohne dass Sie sich die Docker-Datei und die übergeordneten Docker-Dateien ansehen müssen), sondern bietet dem Verbraucher auch die Möglichkeit dazu Verwenden Sie die Lautstärke oder nicht.

Grundsätzlich ist es aus folgenden Gründen schlecht, VOLUMES zu verwenden, wie in dieser Antwort angegeben :

Die VOLUME-Anweisung ist jedoch mit Kosten verbunden.

  • Benutzer wissen möglicherweise nicht, welche unbenannten Volumes erstellt werden, und belegen nach dem Entfernen von Containern weiterhin Speicherplatz auf ihrem Docker-Host.
  • Es gibt keine Möglichkeit, ein in einer Docker-Datei deklariertes Volume zu entfernen. Downstream-Images können keine Pfade zu Pfaden hinzufügen, in denen Volumes vorhanden sind.

Das letztere Problem führt zu solchen Problemen.

Die Option zum Deklarieren eines Volumes zu deklarieren, würde helfen, aber nur, wenn Sie die Volumes kennen, die in der Docker-Datei definiert sind, die das Image generiert hat (und die übergeordneten Docker-Dateien!). Darüber hinaus könnte in neueren Versionen einer Docker-Datei ein VOLUME hinzugefügt werden, das für die Benutzer des Bildes unerwartet zu Problemen führt.

Eine weitere gute Erklärung ( zu dem Orakelbild mit VOLUME , das entfernt wurde ): https://github.com/oracle/docker-images/issues/640#issuecomment-412647328

Weitere Fälle, in denen VOLUME Sachen für Leute kaputt gemacht hat:

Eine Pull-Anforderung zum Hinzufügen von Optionen zum Zurücksetzen von Eigenschaften des übergeordneten Images (einschließlich VOLUME) wurde geschlossen und wird hier diskutiert (und Sie können mehrere Fälle von Personen sehen, die aufgrund von in Docker-Dateien definierten Volumes nachteilig betroffen sind), die einen Kommentar mit einem Gut enthält Erklärung gegen BAND:

Die Verwendung von VOLUME in der Docker-Datei ist wertlos. Wenn ein Benutzer Persistenz benötigt, muss er beim Ausführen des angegebenen Containers eine Datenträgerzuordnung bereitstellen. Es war sehr schwer festzustellen, dass mein Problem, dass ich den Besitz eines Verzeichnisses (/ var / lib / influxdb) nicht festlegen konnte, auf die VOLUME-Deklaration in InfluxDBs Dockerfile zurückzuführen war. Ohne eine Option vom Typ UNVOLUME oder ohne sie vollständig zu entfernen, kann ich nichts an dem angegebenen Ordner ändern. Dies ist nicht ideal, insbesondere wenn Sie sicherheitsbewusst sind und eine bestimmte UID angeben möchten. Das Image sollte ausgeführt werden, um zu vermeiden, dass ein zufälliger Benutzer mit mehr Berechtigungen als erforderlich Software auf Ihrem Host ausführt.

Ich halte EXPOSE auch für schlecht, aber es hat weniger Nebenwirkungen. Das einzig Gute, was ich an VOLUME und EXPOSE sehen kann, ist die Dokumentation, und ich würde sie als gut betrachten, wenn sie nur dazu dienten (ohne Nebenwirkungen).

TL; DR

Ich bin der Meinung, dass die beste Verwendung von VOLUME veraltet ist.

Lucas Basquerotto
quelle