Erstens gibt eine Reihenfolge der Operationen ist. Wenn Sie Ihr Image erstellen, werden Volumes nicht bereitgestellt. Sie werden nur bereitgestellt, wenn Sie den Container ausführen. Wenn Sie mit dem Build fertig sind, werden alle Änderungen nur im Bild und nicht in einem Volume vorhanden sein. Wenn Sie ein Volume in einem Verzeichnis mounten, überlagert es das, was aus dem Image an diesem Speicherort stammt, und blendet diese Inhalte aus der Ansicht aus (mit einer Initialisierungsausnahme, siehe unten).
Als nächstes ist das Volumen Syntax:
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
sagt Docker-compose einen Host-Datenträger aus dem aktuellen Verzeichnis zu /usr/src/app
im Innern des Behälters zu schaffen, und dann /usr/src/app/node_modules
ein anonymes Volumen beibehalten Karte durch Docker. Letzteres erscheint als ein Volumen in docker volume ls
mit einer langen UUID-Zeichenfolge, die relativ nutzlos ist.
Um /usr/src/app/node_modules
einem Ordner auf Ihrem Host zuzuordnen, müssen Sie einen Ordnernamen und einen Doppelpunkt davor einfügen, wie in der Zeile oben. Z.B. /host/dir/node_modules:/usr/src/app/node_modules
.
Benannte Volumes unterscheiden sich ein wenig von Host-Volumes, da Docker diese unter einem Namen verwaltet, den Sie unter docker volume ls
sehen können. Sie verweisen diese Volumes nur mit einem Namen anstelle eines Pfades. So würde node_modules:/usr/src/app/node_modules
ein Volume namens node_modules
erstellen, das Sie in einem Container mit genau diesem Namen bereitstellen können.
Ich divergierte, um benannte Volumes zu beschreiben, weil sie mit einer Funktion kommen, die sich zu einem Gotcha mit Host-Volumes verwandelt. Docker hilft Ihnen mit benannten Volumes, indem Sie sie mit dem Inhalt des Bildes an diesem Ort initialisieren. Wenn also im obigen Beispiel das benannte Volume node_modules
leer (oder neu) ist, kopiert es zuerst den Inhalt des Image unter/usr/src/app/node_modules auf dieses Volume und mountet es dann in Ihrem Container.
Mit Host-Volumes werden Sie nie eine Initialisierung sehen, was auch immer in diesem Speicherort ist, sogar ein leeres Verzeichnis ist alles, was Sie im Container sehen. Es gibt keine Möglichkeit, Inhalte aus dem Bild an diesem Speicherort zu erhalten, um zuerst an diesem Speicherort auf das Host-Volume zu kopieren. Dies bedeutet auch, dass Verzeichnisberechtigungen, die im Container benötigt werden, nicht automatisch vererbt werden. Sie müssen die Berechtigungen für das Hostverzeichnis, das innerhalb des Containers funktionieren soll, manuell festlegen.
Schließlich gibt es noch eine kleine Gotcha mit Docker für Windows und Mac, sie in einer VM laufen, und Ihr Host-Volumes werden an die VM montiert. Um das Volume auf dem Host bereitzustellen, müssen Sie die Anwendung so konfigurieren, dass der Ordner in Ihrem Host für die VM freigegeben wird, und anschließend das Volume in der VM in den Container einhängen. Standardmäßig ist auf dem Mac der Ordner/Users enthalten, wenn Sie jedoch andere Verzeichnisse verwenden, z. a/Projects-Verzeichnis oder auch ein Kleinbuchstabe/Benutzer (Unix und BSD sind case sensitive), Sie werden nicht den Inhalt von Ihrem Mac in den Container sehen.
Mit diesem Basiswissen bedeckt, ist eine mögliche Lösung ist Ihren Workflow neu zu gestalten den Verzeichnisinhalt aus dem Bild auf den Host kopiert zu bekommen. Zuerst müssen Sie die Dateien an einen anderen Ort in Ihrem Bild kopieren. Anschließend müssen Sie die Dateien von diesem Speicherort für gespeicherte Bilder beim Start des Containers in den Speicherort für den Datenträger kopieren. Wenn Sie letzteres tun, sollten Sie beachten, dass Sie den Zweck eines Volumes (Persistenz) vereiteln und möglicherweise etwas Logik hinzufügen möchten, um selektiver zu sein, wenn Sie die Kopie ausführen. Um zu starten, hinzufügen, die eine entrypoint.sh zu Build wie folgt aussieht:
#!/bin/sh
# copy from the image backup location to the volume mount
cp -a /usr/src/app_backup/node_modules/* /usr/src/app/node_modules/
# this next line runs the docker command
exec "[email protected]"
Dann wird Ihr Dockerfile aktualisieren, um den Einstiegspunkt und einen Sicherungsbefehl enthalten:
FROM node:6.3
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install -g babel babel-runtime babel-register mocha nodemon
RUN npm install
# Bundle app source
COPY . /usr/src/app
RUN cp -a /usr/src/app/. /usr/src/app_backup
EXPOSE 1234
ENTRYPOINT [ "/usr/src/app/entrypoint.sh" ]
CMD [ "npm", "start" ]
Und dann fallen die zusätzlichen Volumen von Ihrem docker-compose.yml:
volumes:
- .:/usr/src/app
Mike, hast du eine Lösung gefunden? Ich habe das gleiche Problem: Ich die node_modules Ordner wollen aus dem Behälter an den Host gespiegelt werden, so WebStorm die Abhängigkeiten sehen kann, aber alles, was ich tun kann, ist 'npm install' sowohl auf Host- und Behälter laufen. – Alessandro
habe ich nicht. Entschuldigung –
OK, lass uns hoffen, dass jemand das Kopfgeld sammeln möchte! :) – Alessandro