Docker - Монтирование тома из контейнера в другой (эквивалентный volume_from) в docker-compose 3 - PullRequest
2 голосов
/ 12 апреля 2019

У меня есть два контейнера: nginx & угловой . Контейнер angular содержит код и автоматически извлекается из реестра при появлении новой версии (со сторожевой башней).

Я установил общий объем между angular & nginx , чтобы поделиться кодом от angular до nginx .

  ### Angular #########################################
  angular:
    image: registry.gitlab.com/***/***:staging
    networks:
      - frontend
      - backend
    volumes:
      - client:/var/www/client

  ### NGINX Server #########################################
  nginx:
    image: registry.gitlab.com/***/***/***:staging
    volumes:
      - client:/var/www/client
    depends_on:
      - angular
    networks:
      - frontend
      - backend

volumes:
  client:
networks:
  backend:
  frontend:

Когда я впервые создаю и запускаю среду, все работает. Проблема заключается в том, что при наличии новой версии клиента изображение извлекается, контейнер перестраивается и новая версия кода находится внутри контейнера angular , но в nginx контейнер это все еще старая версия кода клиента .

Общие тома не позволяют мне делать то, что я хочу, потому что мы не можем указать, кто является хостом, возможно ли монтировать тома из одного контейнера в другой?

Заранее спасибо.

EDIT

Контейнер angular предназначен только для обслуживания файлов. Мы могли бы rsync встроенного приложения на сервер на хост-машине, затем подключить том к контейнеру (хост -> гость), но это пошло бы против нашего процесса CI: build app -> build image -> отправить в реестр -> сторожевая башня вытащить новое изображение

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Из вашего комментария:

Для клиента не запущена программа, CI компилирует приложение и создает пользовательский образ, который COPY файлы приложения в /var/www/client. Затем сторожевая башня вытянет это новое изображение и перезапустите контейнер. Контейнер запускается только в демоне с (tail -f /dev/null & wait).

Глядя на это с высокого уровня, я не вижу необходимости вообще иметь два контейнера или тома. Просто создайте свое приложение с помощью многоэтапной сборки, которая генерирует образ nginx с необходимым содержимым:

FROM your_angular_base AS build
COPY src /src
RUN  steps to compile your code

FROM nginx_base as release
...
COPY --from=build /var/www/client/ /var/www/client/
...

Тогда ваш составной файл сокращается до:

...
  ### NGINX Server #########################################
  nginx:
    image: registry.gitlab.com/***/***/***:staging
    networks:
      - frontend
      - backend

networks:
  backend:
  frontend:

Если вы попадаете в ситуацию, когда требуется разделить том между двумя работающими контейнерами, а объем необходимо обновлять при каждом развертывании одного из образов, тогда лучшим местом для этого является сценарий точки входа который копирует файлы из одного места в том. У меня есть пример этого в моей базе докеров со скриптами save-volume и load-volume.

1 голос
/ 12 апреля 2019

Тома Docker не предназначены для совместного использования кода, и я бы предложил пересмотреть этот рабочий процесс.

При первом запуске контейнера с пустым томом и только в первый раз и только , если том уже пуст, Docker заполнит его содержимым из контейнера . Поскольку тома предназначены для хранения данных , и приложение может изменить данные, которые будут сохранены, Docker не перезаписывает данные приложения, если контейнер перезапускается; все, что было в каталоге тома, остается неизменным.

В вашей настройке это означает, что это происходит:

  1. Вы запускаете контейнер angular в первый раз, и поскольку именованный том client пуст, Docker копирует содержимое в него.
  2. Вы запускаете контейнер nginx.
  3. Вы удаляете и перезапускаете контейнер angular; но поскольку именованный том client пуст, Docker оставляет там старый контент.
  4. Контейнер nginx по-прежнему видит старое содержимое.

Для типичного приложения браузера вам на самом деле не нужна запущенная «программа»: после выполнения последовательности Typescript / Webpack / ... выходные данные представляют собой набор полностью статических файлов. В случае Angular существует компилятор Ahead-of-Time , который создает эти статические файлы. Последовательность, которую я бы порекомендовал здесь:

  1. Проверьте локально дерево исходного кода вашего приложения.
  2. Разрабатывайте приложение для браузера изолированно, используя инструменты, ориентированные на разработчика, такие как ng serve или npm start. Поскольку все это выполняется локально, вам не нужно бороться с чем-то специфичным для Docker (сопоставления файловой системы, разрешения, сопоставления портов, ...); это абсолютно нормальная последовательность разработки Javascript. Системные компоненты, которые вам нужны для этого, - это просто Node; это строго проще, чем установка и настройка Docker.
  3. Скомпилируйте ваше приложение в статические файлы с помощью компилятора Angular AOT или Webpack или npm build.
  4. Публикация этих статических файлов в CDN; или связать их в контейнер nginx; или, может быть, встроить их в пользовательский образ.

В последнем случае вы бы не использовали именованный том Docker. Вместо этого вы должны монтировать локальную файловую систему в контейнер. Полный файл docker-compose.yml для этого случая может выглядеть так:

version: '3'
services:
  nginx:
    image: registry.gitlab.com/***/***/***:staging
    volumes:
      - ./client:/var/www/client
    ports:
      - '8000:80'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...