Docker Compose - розподіліть іменований том між кількома контейнерами


107

Я використовую docker-compose і v3. Я намагаюся підключити том у докер:

./appdata:/appdata

Я хотів би мати це як том, а потім посилатися на цей том із декількох контейнерів. Посилання на конфігурацію гучності відображається лише data-volume:як названий том, без значення, тому він не виглядає як вище.

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

Це дає мені:

ПОМИЛКА: У файлі './docker-compose.yml', том 'app-volume' повинен бути відображенням, а не рядком.

Очевидно, я знаю, що мені потрібно змінити volumesпара ключ / значення, але я не впевнений, як це змінити, щоб я міг розподілити обсяг між службами.

Я також перевіряв, volumes_fromале це фактично дозволяє лише успадкування від інших контейнерів. Я бачив, як хтось використовує volumes_fromінший контейнер, який містить потрібне відображення, але з command: trueнабором, щоб контейнер ніколи не запускався, що мені просто здається хаком.

Як я можу це зробити?


Зверніть увагу, я дійсно маю таку роботу:

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

Але це просто дублювання, і це те, що я сподіваюся, що названий том може допомогти мені уникнути :-)


Ви можете знайти відповідь у цій відповіді: stackoverflow.com/a/49920624
Isen Ng

Відповіді:


141

Названі томи можна поділити між контейнерами наступним чином:

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: 

Ось приклад конфігурації, яку я використовую для кращого розуміння. Я відкриваю статичні файли, згенеровані з мого webконтейнера, на іменований том, static-contentякий називається, який потім читає та обслуговує nginxконтейнер:

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
Де ви встановлюєте розташування static_contentв хост-файловій системі?
Тревіс Ведмідь

10
Пробіл у app-volume: location_in_the_containerпомилково.
hasufell

4
Що робити, якщо /usr/src/appв nginxконтейнері та /usr/src/app/publicв webконтейнері обидва отримали оригінальний вміст, який із них буде використаний і чому?
jallen0927

2
@TravisBear для цього випадку використання (обмін даними між контейнерами) насправді не потрібно мати його на хості. Приклад зі статичними даними чудовий - ви виконуєте collectstaticв одному контейнері і хочете, щоб результати були доступні в іншому, але вас не хвилює хост-папка
The Godfather

7
@Kannaj TravisBear питання, яке правильно визначає проблему, яку я вважаю найбільш заплутаною. Як у складеному файлі можна вказати, де розміщений названий том? Я не хочу залишати його за допомогою докерного двигуна, щоб визначити, де зберігати названий том на хості, я хочу вказати шлях.
Бен Коллінз

33

Це вирішує це без використання названих томів:

      volumes:
          - ./appdata:/appdata

Отже, це виглядає так:

services:

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

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

4
Ах, приємні терміни! Я зробив це вище (див. Мою зміну). Однак, схоже, ми все ще дублюємо відображення. Якщо я використовую це понад 3 контейнери, він стає великим. Чи можемо ми використовувати названі контейнери, щоб уникнути цього дублювання?
Джимбо

Вся справа в тому, що названі томи - це не лише те, що стосується синтаксису та ясного коду. Це створить об'єм всередині каталогу встановлення даних докер, і ви не матимете там своїх локальних файлів (./appdata). Це вам корисно все-таки?
Роберт

1
Мені, безумовно, потрібно ./appdata, саме це я і намагаюся зробити. Залиште цю відповідь, хоча :) +1
Джимбо

2
Що станеться, якщо у мене є два контейнери одного зображення, завантажуючи файл (через службу завантаження файлів) в один контейнер, він буде доступний в іншому? якщо ні, то як це зробити?
магноз

0

Докер з назвами томів був видалений, починаючи з версії docker-compose 3.

Однак ви можете використовувати поля розширення, щоб уникнути дублювання джерела томів і не допустити себе в майбутньому помилок:

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

ПРИМІТКА. Ця функція доступна, починаючи з формату файлу версії 3.4.


Якщо * сервіс-том є лише вказівником на встановлене вище значення, це виглядає приголомшливо ... Мені доведеться спробувати.
Джимбо

@Jimbo, так, також зауважте, що версія файлу докер-композиції має бути 3,4+
Андрій Іванейко

2
Іменовані томи, які також називаються volumesполем вищого рівня , здаються, все ще є предметом у версії 3docker-compose .
Алекс Повель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.