Docker Compose - Partager le volume nommé entre plusieurs conteneurs

107

J'utilise docker-compose et v3. J'essaye de monter un volume dans le docker:

./appdata:/appdata

Je voudrais avoir ceci comme volume, puis référencer ce volume à partir de plusieurs conteneurs. La référence de configuration de volume s'affiche uniquement data-volume:sous la forme d'un volume nommé, sans valeur, donc cela ne ressemble pas à ce qui précède.

services:

    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes:
            - app-volume

    php:
        build: ./php/
        expose:
            - 9000
        volumes:
            - app-volume

volumes:
     app-volume: ./appdata:/appdata

Cela me donne:

ERREUR: dans le fichier './docker-compose.yml', le volume 'app-volume' doit être un mappage et non une chaîne.

Évidemment, je sais que j'ai besoin de changer la volumespaire clé / valeur, mais je ne sais pas comment changer cela pour pouvoir partager un volume entre les services.

J'ai également vérifié, volumes_frommais cela permet simplement l'héritage d'autres conteneurs. J'ai vu quelqu'un utiliser volumes_fromsur un autre conteneur qui contient le mappage souhaité, mais avec command: trueset pour que le conteneur ne soit jamais réellement exécuté, ce qui me semble être un hack.

Comment puis-je faire ceci?


Remarque, je fais fonctionner les éléments suivants:

nginx:
    volumes:
        - ./appdata:/appdata
php:
    volumes:
        - ./appdata:/appdata

Mais ce n'est que de la duplication et j'espère qu'un volume nommé pourrait m'aider à éviter :-)

Jimbo
la source
Vous pouvez trouver la réponse dans cette réponse: stackoverflow.com/a/49920624
Isen Ng

Réponses:

141

Les volumes nommés peuvent être partagés entre les conteneurs de la manière suivante:

services:
    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes:
            - app-volume:location_in_the_container

    php:
        build: ./php/
        expose:
            - 9000
        volumes:
            - app-volume:location_in_the_container

volumes:
     app-volume: 

Voici un exemple de configuration que j'utilise pour une meilleure compréhension. J'expose les fichiers statiques générés à partir de mon webconteneur à un volume nommé appelé static-contentqui est ensuite lu et servi par le nginxconteneur:

services:
  nginx:
    container_name: nginx
    build: ./nginx/

    volumes:
      - static-content:/usr/src/app

  web:
    container_name: web
    env_file: .env
    volumes:
      - static-content:/usr/src/app/public
    environment:
      - NODE_ENV=production

    command: npm run package

volumes:
  static-content:
Kannaj
la source
79
Où définissez-vous l'emplacement static_contentsur le système de fichiers hôte?
Travis Bear
10
L'espace blanc app-volume: location_in_the_containerest faux.
hasufell
4
Et si /usr/src/apple nginxconteneur et /usr/src/app/publicle webconteneur contenaient tous deux un contenu original, lequel sera utilisé et pourquoi?
jallen0927
2
@TravisBear pour ce cas d'utilisation (partage de données entre conteneurs), il n'est pas vraiment nécessaire de l'avoir sur l'hôte. L'exemple avec des données statiques est génial - vous exécutez collectstaticdans un conteneur et voulez que les résultats soient disponibles dans un autre, mais vous ne vous souciez pas du dossier hôte
The Godfather
7
La question de @Kannaj TravisBear est celle qui identifie correctement le problème que je trouve le plus déroutant. Comment, dans le fichier de composition, pouvez-vous spécifier la provenance du volume nommé? Je ne veux pas laisser au moteur docker le soin de déterminer où stocker le volume nommé sur l'hôte, je veux spécifier un chemin.
Ben Collins
33

Cela résout le problème sans utiliser de volumes nommés:

      volumes:
          - ./appdata:/appdata

Donc, ça ressemble à:

services:

  nginx:
      build: ./nginx/
      ports:
          - 80:80
      links:
          - php
      volumes:
          - ./appdata:/appdata

  php:
      build: ./php/
      expose:
          - 9000
      volumes:
          - ./appdata:/appdata
Robert
la source
4
Ah, bon timing! Je l'ai fait ci-dessus (voir mon changement). Cependant, il semble que nous dupliquions toujours le mappage. Si j'utilise plus de 3 conteneurs, ça devient gros. Pouvons-nous utiliser des conteneurs nommés pour éviter cette duplication?
Jimbo
Le fait est que les volumes nommés ne concernent pas seulement la syntaxe et le code clair. Cela créera un volume dans le répertoire d'installation des données de docker et vous n'y trouverez pas vos fichiers locaux (le ./appdata). Cela vous est-il utile de toute façon?
Robert
1
J'ai vraiment besoin du ./appdata, c'est ce que j'essaye de faire. Laissez cette réponse ici :) +1
Jimbo
2
Que se passe-t-il si j'ai deux conteneurs de la même image, en téléchargeant un fichier (via le service de téléchargement de fichiers) dans un conteneur, il sera disponible dans l'autre? sinon, comment puis-je faire ça?
magnoz
0

Le docker nommé volumes a été supprimé à partir de la version docker-compose 3.

Cependant, vous pouvez utiliser des champs d' extension pour éviter de dupliquer la source des volumes et vous empêcher de futures fautes de frappe:

version: '3.5'

x-services-volume:
  &services-volume
  type: bind
  source: ./appdata
  target: /appdata

services:

    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes: *services-volume

    php:
        build: ./php/
        expose:
            - 9000
        # Use same way as for nginx if target override not needed.
        volumes:
            - <<: *services-volume
            target: /opt/target-override

REMARQUE: cette fonctionnalité est disponible à partir du format de fichier de la version 3.4.

Andriy Ivaneyko
la source
Si le * services-volume est juste un pointeur vers la valeur définie ci-dessus, cela semble génial ... je vais devoir l'essayer.
Jimbo le
@Jimbo oui, il est, notez également que la version du fichier docker-compose sera 3.4+
Andriy Ivaneyko
2
Les volumes nommés, alias le volumeschamp de premier niveau , semblent toujours être une chose dans la v3 dedocker-compose .
Alex Povel le