Docker Compose: consente di condividere il volume denominato tra più contenitori


107

Sto usando docker-compose e v3. Sto provando a montare un volume nella finestra mobile:

./appdata:/appdata

Mi piacerebbe averlo come volume e quindi fare riferimento a quel volume da più contenitori. Il riferimento alla configurazione del volume viene visualizzato solo data-volume:come volume denominato, senza valore, quindi non ha l'aspetto di cui sopra.

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

Questo mi dà:

ERRORE: nel file "./docker-compose.yml", il volume "app-volume" deve essere una mappatura e non una stringa.

Ovviamente so che ho bisogno di cambiare la volumescoppia chiave / valore, ma non sono sicuro di come cambiarlo in modo da poter condividere un volume tra i servizi.

Ho anche verificato volumes_fromma questo in effetti consente solo l'ereditarietà da altri contenitori. Ho visto qualcuno usare volumes_fromsu un altro contenitore che contiene la mappatura che desidera, ma con command: trueset in modo che il contenitore non venga mai effettivamente eseguito, il che a me sembra solo un hack.

Come posso fare questo?


Nota, io non hanno il seguente funzionamento:

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

Ma questa è solo una duplicazione ed è qualcosa che spero che un volume con nome possa aiutarmi a evitare :-)


Puoi trovare la risposta in questa risposta: stackoverflow.com/a/49920624
Isen Ng

Risposte:


141

I volumi denominati possono essere condivisi tra i contenitori nel modo seguente:

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: 

Ecco un esempio di configurazione che uso per una migliore comprensione. Sto esponendo i file statici generati dal mio webcontenitore a un volume denominato chiamato static-contentche viene quindi letto e servito dal nginxcontenitore:

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:

79
Dove si imposta la posizione di static_contentsul filesystem host?
Travis Bear

10
Lo spazio vuoto in app-volume: location_in_the_containerè sbagliato.
hasufell

4
E se /usr/src/appnel nginxcontenitore e /usr/src/app/publicnel webcontenitore entrambi avessero contenuto originale, quale verrà utilizzato e perché?
jallen0927

2
@TravisBear per questo caso d'uso (condivisione di dati tra contenitori) non è davvero necessario averlo sull'host. L'esempio con dati statici è ottimo: esegui collectstaticin un contenitore e desideri che i risultati siano disponibili in un altro, ma non ti interessa la cartella host
The Godfather

7
La domanda di @Kannaj TravisBear è quella che identifica correttamente il problema che trovo più confuso. In che modo nel file di composizione è possibile specificare la provenienza del volume denominato? Non voglio lasciare che sia il motore Docker a determinare dove memorizzare il volume denominato sull'host, voglio specificare un percorso.
Ben Collins

33

Questo lo risolve senza utilizzare volumi denominati:

      volumes:
          - ./appdata:/appdata

Quindi, sembra:

services:

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

  php:
      build: ./php/
      expose:
          - 9000
      volumes:
          - ./appdata:/appdata

4
Ah, bel tempismo! L'ho fatto sopra (vedi la mia modifica). Tuttavia, sembra che stiamo ancora duplicando la mappatura. Se lo uso su 3 contenitori, diventa grande. Possiamo usare contenitori con nome per evitare questa duplicazione?
Jimbo

Il fatto è che i volumi con nome non riguardano solo la sintassi e il codice chiaro. Creerà un volume all'interno della directory di installazione dei dati docker e non avrai i tuoi file locali lì (il ./appdata). Ti è utile comunque?
Robert

1
Ne ho decisamente bisogno ./appdata, questo è quello che sto cercando di fare. Lascia questa risposta qui però :) +1
Jimbo

2
Cosa succede se ho due contenitori della stessa immagine, caricando un file (tramite il servizio di caricamento file) in un contenitore, sarà disponibile nell'altro? se no, come posso farlo?
magnoz

0

I volumi denominati docker sono stati rimossi a partire dalla versione docker-compose 3.

Tuttavia, puoi utilizzare i campi di estensione per evitare di duplicare l'origine dei volumi e prevenire futuri errori di battitura:

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

NOTA: questa funzionalità è disponibile a partire dalla versione 3.4 del formato file.


Se * services-volume è solo un puntatore al valore impostato sopra, sembra fantastico ... dovrò provarlo.
Jimbo

@Jimbo sì, lo è, nota anche che la versione del file docker-compose sarà 3.4+
Andriy Ivaneyko

2
I volumi denominati, ovvero il volumescampo di primo livello , sembrano essere ancora una cosa nella v3 didocker-compose .
Alex Povel
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.