Comment monter un répertoire hôte en tant que volume dans docker compose

126

J'ai un environnement de développement que je suis en train de docker et j'aimerais pouvoir charger mes modifications sans avoir à reconstruire les images docker. J'utilise docker compose car redis est l'une des dépendances de mon application et j'aime pouvoir lier un conteneur redis

J'ai deux conteneurs définis dans mon docker-compose.yml:

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

redis:
    image: redis
    ports:
        - "6379"

Je suis arrivé au point dans nodele fichier docker de mon application où j'ajoute un volume, mais comment monter le répertoire de l'hôte dans le volume afin que toutes mes modifications en direct du code soient reflétées dans le conteneur?

Voici mon Dockerfile actuel:

# 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"]

Mon projet ressemble à ceci:

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

Réponses:

137

Consultez leur documentation

À partir de l'apparence de celui-ci, vous pouvez faire ce qui suit sur votre docker-compose.yml

volumes:
    - ./:/app
jkris
la source
2
Je l'ai essayé, cela n'a pas fonctionné:Error: Cannot find module '/data/app.js'
Amin Shah Gilani
2
attendez ... votre VOLUME et WORKDIR indiquent /app/pourquoi votre CMD pointe vers/data
jkris
1
C'était une erreur! Merci de le saisir! Corrigé, et maintenant je comprends, Error: Cannot find module 'express'je vais essayer quelques trucs maintenant.
Amin Shah Gilani
3
Pour les conteneurs Windows, vous voudrez un chemin de style Windows comme - .:c:/app(cela m'a fait trébucher)
JohnnyFun
86

Il y a quelques options

Syntaxe courte

En utilisant le host : guestformat, vous pouvez effectuer l'une des opérations suivantes:

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

Syntaxe longue

À partir de docker-compose v3.2, vous pouvez utiliser une syntaxe longue qui permet la configuration de champs supplémentaires qui peuvent être exprimés sous forme abrégée tels que mount type(volume, bind ou tmpfs) et 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:

Consultez https://docs.docker.com/compose/compose-file/#long-syntax-3 pour plus d'informations.

GreensterRox
la source
21

Si vous souhaitez monter un répertoire hôte particulier ( /disk1/prometheus-datadans l'exemple suivant) en tant que volume dans la volumessection du fichier Docker Compose YAML, vous pouvez le faire comme ci-dessous, par exemple:

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

À propos, dans Dockerfile de prometheus, vous pouvez trouver l' VOLUMEinstruction ci-dessous, qui la marque comme contenant des volumes montés en externe à partir de l'hôte natif, etc. (Remarque cependant: cette instruction n'est pas indispensable pour monter un volume dans un conteneur.) :

Dockerfile

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

Réf:

Yuci
la source
Cela a fonctionné. Merci. Où est la documentation pour le localtype de pilote?
mmell
@mmell La documentation est le premier lien Refs ( docs.docker.com/compose/compose-file/#driver ) Il lit: Spécifiez le pilote de volume à utiliser pour ce volume. Par défaut, le pilote que le moteur Docker a été configuré pour utiliser, qui dans la plupart des cas estlocal
Yuci
1
@mmell, vous pouvez trouver plus de détails à partir de cette question: stackoverflow.com/questions/42195334/…
Yuci
Comment avez-vous connu les paramètres driver_opts: o: bind type: none?
mmell
1
@mmell Fondamentalement, ces options dépendent du pilote, et le localpilote intégré sous Linux accepte des options similaires à la commande de montage linux: man7.org/linux/man-pages/man8/mount.8.html . Vous pouvez trouver plus de discussion sur github.com/moby/moby/issues/19990#issuecomment-248955005 , et stackoverflow.com/questions/35841241/...
Yuci
9

C'était deux choses:

J'ai ajouté le volume dans docker-compose.yml:

node:
    volumes:
        - ./node:/app

J'ai déplacé les npm install && nodemon app.jsmorceaux dans un CMDcar RUNajoute des éléments au système de fichiers Union, et mon volume ne fait pas partie d'UFS.

# 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
la source
2

nous devons créer votre propre volume docker mappé avec le répertoire hôte avant de mentionner dans le docker-compose.yml comme externe

1.Créer un volume nommé partage

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

2. utilisez-le dans votre 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

De cette façon, nous pouvons partager le même répertoire avec de nombreux services s'exécutant dans différents conteneurs

Mukundhan
la source
pourquoi ai-je besoin d'ipc: host?
Vahid Noormofidi le
cela n'est nécessaire que lorsque nous devons lier le réseau à l'hôte lui-même.
Mukundhan