2016-07-17 12 views
9

Ich bin ziemlich neu mit Docker und ich wollte den node_modules Ordner auf meinem Computer (für Debugging-Zwecke) zuordnen.docker-komponieren Volumen auf node_module aber ist leer

Das ist mein Docker-compose.yml

web: 
    build: . 
    ports: 
    - "3000:3000" 
    links: 
    - db 
    environment: 
    PORT: 3000 
    volumes: 
    - .:/usr/src/app 
    - /usr/src/app/node_modules 
db: 
    image: mongo:3.3 
    ports: 
    - "27017:27017" 
    command: "--smallfiles --logpath=/dev/null" 

ich mit Docker für Mac bin. Wenn ich docker-compose up -d ausführen, gehen alle richtig, aber es erstellt einen Ordner node_modules auf meinem Computer, aber es ist leer. Ich gehe in den Bash meines Containers und ls node_modules, alle Pakete waren da.

Wie bekomme ich den Inhalt auf dem Container auch auf meinem Computer?

Danke

+0

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

+0

habe ich nicht. Entschuldigung –

+1

OK, lass uns hoffen, dass jemand das Kopfgeld sammeln möchte! :) – Alessandro

Antwort

5

TL; DR Arbeits Beispiel Klon und versuchen:https://github.com/xbx/base-server


Sie benötigen einen node_modules in Ihrem Computer (außerhalb Bild) zum Debuggen zuerst (bevor der Behälter laufen).

Wenn Sie Debug nur wollen node_modules:

volumes: 
    - /path/to/node_modules:/usr/src/app/node_modules 

Wenn Sie debuggen möchten sowohl den Code und die node_modules:

volumes: 
    - .:/usr/src/app/ 

Denken Sie daran, dass Sie npm install mindestens einmal außerhalb des Behälters ausgeführt werden müssen (oder kopiere die npm_module, die docker build erzeugt). Lass mich jetzt, wenn du mehr Details brauchst.


bearbeiten. Also, ohne die Notwendigkeit von NPM in OSX, können Sie:

  1. docker build und dann docker cp <container-id>:/path/to/node-modules ./local-node-modules/. Dann in Ihrem docker-compose.yml mount diese Dateien und probleme was auch immer Sie wollen.
  2. Oder, docker build und dort (Dockerfile) tun Sie die npm install in einem anderen Verzeichnis. Dann in Ihrem Befehl (CMD oder docker-compose Befehl) die Kopie (cp) in das richtige Verzeichnis, aber dieses Verzeichnis wird leer von Ihrem Computer (ein Volume in der Docker-compose.yml) gemountet und dann Problem, was Sie wollen.

bearbeiten 2. (Option 2) Arbeitsbeispiel, Klon und versuchen:https://github.com/xbx/base-server ich es tat alles automatisch in diesem Repo aus den Ihnen gegabelt.

Dockerfile

FROM node:6.3 

# Install app dependencies 
RUN mkdir /build-dir 
WORKDIR /build-dir 
COPY package.json /build-dir 
RUN npm install -g babel babel-runtime babel-register mocha nodemon 
RUN npm install 

# Create app directory 
RUN mkdir -p /usr/src/app 
WORKDIR /usr/src/app 
RUN ln -s /build-dir/node_modules node_modules 

# Bundle app source 
COPY . /usr/src/app 

EXPOSE 1234 
CMD [ "npm", "start" ] 

Docker-compose.yml

web: 
    build: . 
    ports: 
    - "1234:1234" 
    links: 
    - db # liaison avec la DB 
    environment: 
    PORT: 1234 
    command: /command.sh 
    volumes: 
    - ./src/:/usr/src/app/src/ 
    - ./node_modules:/usr/src/app/node_modules 
    - ./command.sh:/command.sh 
db: 
    image: mongo:3.3 
    ports: 
    - "27017:27017" 
    command: "--smallfiles --logpath=/dev/null" 

command.sh

#!/bin/bash 

cp -r /build-dir/node_modules/ /usr/src/app/ 

exec npm start 

Bitte, meine Repo-Klon und docker-compose up tun. Es macht was du willst. PS: Es kann verbessert werden, um das gleiche in einer besseren Weise (dh Best Practices, etc.) zu tun

Ich bin in OSX und es funktioniert für mich.

+1

Da 'npm install' plattformabhängig ist, führt das Ausführen auf dem Host möglicherweise zu plattformübergreifenden Problemen (host = mac, container = debian). – gesellix

+0

Scheint, wie Sie vorschlagen manuell die 'npm install' Ergebnisse auf das Volumen zu kopieren. Gibt es einen Grund, warum Sie es lieber manuell und nicht automatisch als Teil des Build- und Einstiegspunkts machen, wie ich es in meiner Antwort geschrieben habe? – BMitch

+0

Funktioniert diese symbolische Verbindung beim Einhängen in ein leeres Volume? Das sieht der Antwort sehr ähnlich, die ich zuvor gepostet habe. – BMitch

0

Änderung:

volumes: 
    - .:/usr/src/app 
    - /usr/src/app/node_modules 

TO:

volumes: 
    - .:/usr/src/app 

Und es wird die node_modules in Ihrem lokalen abgebildet Volumen setzen. Wie Sie es haben, wird die /usr/src/app/node_modules in verschiedenen Volumen gespeichert werden, die Sie benötigen, um den Speicherort zu finden docker inspect {container-name}. Wenn Sie den Speicherort angeben möchten, geben Sie es mögen:

- /path/to/my_node_modules:/usr/src/app/node_modules

+0

Ich habe es zuerst versucht, aber wenn ich '-/usr/src/app/node_modules' nicht in meinen docker-copose.yml-Volumes habe, findet meine App die Pakete nicht. Es ist so, als hätten sie nie installiert. Wenn ich es hinzufüge, funktioniert mein Knoten js-Datei, aber der Ordner bleibt leer. –

+0

können Sie Ihre Dockerfile für die Knoten-App posten? – ldg

+0

https://github.com/DWboutin/base-server/blob/master/Dockerfile –

1

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 
+0

Ich glaube, Sie reparieren müssen, wie das Laufwerk aktiviert ist. Nicht nur das zusätzliche Volumen fallen lassen. Wie ich in meiner Antwort geschrieben habe. – Robert

+0

Wenn sie wollen 'node_modules' in' gespeichert werden./Node_modules' der oben genannten Arbeiten. Andernfalls müssen sie, wie Sie gezeigt haben, ein anderes Volume-Mount angeben. – BMitch

+0

Wenn ich mich nicht falsch, ein Volumens wie das specifiing, erstellt es ein anonymes Volumen. Es fehlt das lokale (Host) -Verzeichnis. – Robert