Wie mounte ich ein Host-Verzeichnis als Volume in Docker Compose?

125

Ich habe eine Entwicklungsumgebung, die ich dockerisiere, und ich möchte die Möglichkeit haben, meine Änderungen zu laden, ohne Docker-Images neu erstellen zu müssen. Ich verwende Docker Compose, weil Redis eine der Abhängigkeiten meiner App ist und ich es mag, einen Redis-Container verknüpfen zu können

Ich habe zwei Container in meinem definiert docker-compose.yml:

node:
    build: ./node
    links:
        - redis
    ports:
        - "8080"
    env_file:
        - node-app.env

redis:
    image: redis
    ports:
        - "6379"

Ich habe den Punkt in nodeder Docker-Datei meiner App erreicht, an dem ich ein Volume hinzufüge. Wie kann ich jedoch das Host-Verzeichnis in das Volume einbinden, damit alle meine Live-Änderungen am Code im Container angezeigt werden?

Hier ist meine aktuelle Docker-Datei:

# Set the base image to Ubuntu
FROM    node:boron

# File Author / Maintainer
MAINTAINER Amin Shah Gilani <[email protected]>

# Install nodemon
RUN npm install -g nodemon

# Add a /app volume
VOLUME ["/app"]

# TODO: link the current . to /app

# Define working directory
WORKDIR /app

# Run npm install
RUN npm install

# Expose port
EXPOSE  8080

# Run app using nodemon
CMD ["nodemon", "/app/app.js"]

Mein Projekt sieht so aus:

/
- docker-compose.yml
- node-app.env
- node/
  - app.js
  - Dockerfile.js
Amin Shah Gilani
quelle

Antworten:

137

Überprüfen Sie ihre Dokumentation

So wie es aussieht, können Sie auf Ihrer docker-compose.yml Folgendes tun

volumes:
    - ./:/app
jkris
quelle
2
Versuchte es, es hat nicht funktioniert:Error: Cannot find module '/data/app.js'
Amin Shah Gilani
2
warte .. dein VOLUME und WORKDIR zeigen darauf, /app/warum dein CMD auf/data
jkris
1
Das war ein fehler! Danke, dass du das verstanden hast! Behoben, und jetzt werde Error: Cannot find module 'express'ich ein paar Dinge ausprobieren.
Amin Shah Gilani
3
Für Windows-Container - .:c:/app
benötigen
86

Es gibt einige Optionen

Kurze Syntax

Mit dem host : guestFormat können Sie eine der folgenden Aktionen ausführen:

volumes:
  # Just specify a path and let the Engine create a volume
  - /var/lib/mysql

  # Specify an absolute path mapping
  - /opt/data:/var/lib/mysql

  # Path on the host, relative to the Compose file
  - ./cache:/tmp/cache

  # User-relative path
  - ~/configs:/etc/configs/:ro

  # Named volume
  - datavolume:/var/lib/mysql

Lange Syntax

Ab Docker-Compose v3.2 können Sie eine lange Syntax verwenden, mit der zusätzliche Felder konfiguriert werden können, die in Kurzform ausgedrückt werden können, z. B. mount type(volume, bind oder tmpfs) und read_only.

version: "3.2"
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - type: volume
        source: mydata
        target: /data
        volume:
          nocopy: true
      - type: bind
        source: ./static
        target: /opt/app/static

networks:
  webnet:

volumes:
  mydata:

Weitere Informationen finden Sie unter https://docs.docker.com/compose/compose-file/#long-syntax-3 .

GreensterRox
quelle
21

Wenn Sie ein bestimmtes Hostverzeichnis ( /disk1/prometheus-dataim folgenden Beispiel) als Volume im volumesAbschnitt der Docker Compose YAML-Datei bereitstellen möchten, können Sie dies wie folgt tun, z.

version: '3'

services:
  prometheus:
    image: prom/prometheus
    volumes:
      - prometheus-data:/prometheus

volumes:
  prometheus-data:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /disk1/prometheus-data

Übrigens finden Sie in der Docker-Datei von prometheus die folgende VOLUMEAnweisung, die das Speichern von extern gemounteten Volumes vom nativen Host usw. kennzeichnet. (Beachten Sie jedoch, dass diese Anweisung kein Muss ist, um ein Volume in einen Container zu mounten.) ::

Dockerfile

...
VOLUME ["/prometheus"]
...

Refs:

Yuci
quelle
Das hat funktioniert. Vielen Dank. Wo ist die Dokumentation für den localFahrertyp?
mmell
@mmell Die Dokumentation ist der erste Refs-Link ( docs.docker.com/compose/compose-file/#driver ). Sie lautet: Geben Sie an, welcher Volume-Treiber für dieses Volume verwendet werden soll. Der Standardwert ist der Treiber, für den die Docker Engine konfiguriert wurde. In den meisten Fällen handelt es sich dabei umlocal
Yuci
1
@mmell, können Sie mehr Details von dieser Frage finden: stackoverflow.com/questions/42195334/…
Yuci
Woher kannten Sie die Einstellungen in driver_opts: o: bind type: none?
mmell
1
@mmell Grundsätzlich sind diese Optionen treiberabhängig, und der unter localLinux integrierte Treiber akzeptiert Optionen, die dem Linux-Mount-Befehl ähnlich sind: man7.org/linux/man-pages/man8/mount.8.html . Weitere Informationen finden Sie unter github.com/moby/moby/issues/19990#issuecomment-248955005 und stackoverflow.com/questions/35841241/…
Yuci
9

Es waren zwei Dinge:

Ich habe das Volume hinzugefügt in docker-compose.yml:

node:
    volumes:
        - ./node:/app

Ich habe die npm install && nodemon app.jsTeile in ein verschoben, CMDweil RUNdem Union-Dateisystem Dinge hinzugefügt wurden und mein Volume nicht Teil von UFS ist.

# Set the base image to Ubuntu
FROM    node:boron

# File Author / Maintainer
MAINTAINER Amin Shah Gilani <[email protected]>

# Install nodemon
RUN npm install -g nodemon

# Add a /app volume
VOLUME ["/app"]

# Define working directory
WORKDIR /app

# Expose port
EXPOSE  8080

# Run npm install
CMD npm install && nodemon app.js
Amin Shah Gilani
quelle
1

Wir müssen Ihr eigenes Docker-Volume erstellen, das dem Host-Verzeichnis zugeordnet ist, bevor wir es in der docker-compose.yml als extern erwähnen

1.Erstellen Sie das Volume mit dem Namen share

docker volume create --driver local \
    --opt type=none \
    --opt device=/home/mukundhan/share \
    --opt o=bind share

2.Verwenden Sie es in Ihrem Docker-Compose

version: "3"

volumes:
  share:
    external: true

services:
  workstation:
    container_name: "workstation"
    image: "ubuntu"
    stdin_open: true
    tty: true
    volumes:
      - share:/share:consistent
      - ./source:/source:consistent
    working_dir: /source
    ipc: host
    privileged: true
    shm_size: '2gb'
  db:
    container_name: "db"
    image: "ubuntu"
    stdin_open: true
    tty: true
    volumes:
      - share:/share:consistent
    working_dir: /source
    ipc: host

Auf diese Weise können wir dasselbe Verzeichnis mit vielen Diensten teilen, die in verschiedenen Containern ausgeführt werden

Mukundhan
quelle
Warum brauche ich ipc: host?
Vahid Noormofidi
Dies ist nur erforderlich, wenn das Netzwerk an den Host selbst gebunden werden muss.
Mukundhan