Docker Compose - Udostępnij nazwany wolumin między wieloma kontenerami


116

Używam docker-compose i v3. Próbuję zamontować wolumin w dockerze:

./appdata:/appdata

Chciałbym mieć to jako objętość, a następnie odwoływać się do tej objętości z wielu pojemników. Referencyjna konfiguracja objętość tylko pokazuje data-volume:jak nazwanego objętości, bez wartości, więc nie wyglądają jak wyżej.

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

To daje mi:

BŁĄD: W pliku „./docker-compose.yml” wolumin „app-volume” musi być mapowaniem, a nie ciągiem.

Oczywiście wiem, że muszę zmienić volumesparę klucz / wartość, ale nie jestem pewien, jak to zmienić, aby móc dzielić wolumen między usługami.

Sprawdziłem również, volumes_fromale to skutecznie pozwala tylko na dziedziczenie z innych kontenerów. Widziałem, jak ktoś używa volumes_frominnego kontenera, który zawiera żądane mapowanie, ale zcommand: true ustawieniem, aby kontener nigdy nie był faktycznie uruchamiany, co dla mnie wydaje się po prostu włamaniem.

Jak mogę to zrobić?


Uwaga, to nie mają następującą pracę:

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

Ale to tylko powielanie i mam nadzieję, że nazwany tom mógłby mi pomóc uniknąć :-)


Możesz znaleźć odpowiedź w tej odpowiedzi: stackoverflow.com/a/49920624
— Isen Ng

Odpowiedzi:


154

Nazwane woluminy można udostępniać w kontenerach w następujący sposób:

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: 

Oto przykładowa konfiguracja, której używam do lepszego zrozumienia. Wystawiam pliki statyczne wygenerowane z mojego webkontenera do nazwanego woluminu, static-contentktóry jest następnie odczytywany i obsługiwany przez nginxkontener:

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:

80
Gdzie ustawiasz lokalizację w static_contentsystemie plików hosta?
— Travis Bear

10
Białe spacje app-volume: location_in_the_containersą błędne.
— hasufell

6
A co jeśli /usr/src/appw nginxkontenerze i /usr/src/app/publicw webkontenerze obie otrzymają oryginalną zawartość, która zostanie wykorzystana i dlaczego?
— jallen0927

2
@TravisBear w tym przypadku użycia (udostępnianie danych między kontenerami) tak naprawdę nie ma potrzeby posiadania go na hoście. Przykład z danymi statycznymi jest świetny - wykonujesz collectstaticw jednym kontenerze i chcesz, aby wyniki były dostępne w innym, ale nie obchodzi Cię folder hosta
— Ojciec chrzestny

7
Pytanie @Kannaj TravisBear jest tym, które poprawnie identyfikuje problem, który uważam za najbardziej zagmatwany. W jaki sposób w pliku redagowania można określić, skąd pochodzi nazwany wolumin? Nie chcę pozostawiać tego silnikowi dokera, aby określić, gdzie przechowywać nazwany wolumin na hoście, chcę określić ścieżkę.
— Ben Collins,

35

To rozwiązuje problem bez używania nazwanych woluminów:

      volumes:
          - ./appdata:/appdata

Wygląda więc na to:

services:

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

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

4
Ach, niezłe wyczucie czasu! Zrobiłem to powyżej (zobacz moją zmianę). Wygląda jednak na to, że nadal kopiujemy mapowanie. Jeśli użyję tego powyżej 3 pojemników, zrobi się duży. Czy możemy używać nazwanych kontenerów, aby uniknąć tego powielania?
— Jimbo

Rzecz w tym, że nazwane woluminy to nie tylko składnia i przejrzysty kod. Spowoduje to utworzenie woluminu w katalogu instalacyjnym danych Dockera i nie będziesz mieć tam swoich plików lokalnych (plik ./appdata). Czy jest to dla ciebie przydatne?
— Robert

2
Zdecydowanie potrzebuję ./appdata, to jest to, co próbuję zrobić. Zostaw tę odpowiedź tutaj :) +1
— Jimbo

3
Co się stanie, jeśli mam dwa kontenery tego samego obrazu, przesyłając plik (za pośrednictwem usługi przesyłania plików) w jednym kontenerze, będzie on dostępny w drugim? jeśli nie, jak mogę to zrobić?
— magnoz

5

Docker o nazwie woluminy zostały usunięte począwszy od wersji docker-compose 3.

Możesz jednak użyć pól rozszerzeń, aby uniknąć powielania źródła woluminów i zapobiec przyszłym literówkom:

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

UWAGA: Ta funkcja jest dostępna od wersji 3.4.


Jeśli * services-volume jest tylko wskaźnikiem do wartości ustawionej powyżej, wygląda to niesamowicie ... Muszę spróbować.
— Jimbo

@Jimbo tak, to jest, pamiętaj również, że wersja pliku docker-compose będzie 3.4+
— Andriy Ivaneyko

2
Nazwane woluminy, czyli pola najwyższego poziomu volumes, nadal wydają się być czymś w wersji 3 programudocker-compose .
— Alex Povel

Wypróbowałem dokładnie to podejście do udostępniania danych między trzema kontenerami i hostem. W moim przypadku struktury folderów w kontenerach są równe. Wygląda na to, że działa to zgodnie z oczekiwaniami. Nie dostaję, który kontener (lub host) ma uprzywilejowane prawo przy ponownym uruchomieniu? Co mam na myśli: podczas wydawania docker-compose down, wewnętrzny system plików każdego kontenera jest zapisywany gdzieś wewnętrznie. Kiedy teraz zmienię dane w folderze hosta i ponownie utworzę okno dokowane: Jaka jest reguła dotycząca zawartości w folderze udostępnionym? Czy dane z hosta zastąpią dane zapisane wewnętrznie? Thx!
— and0r

@ and0r jest zachowywany i taki sam dla wszystkich kontenerów, więc zawartość zostanie zachowana.
— Andriy Ivaneyko
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.