Docker - Невозможно обмениваться данными между контейнерами внутри тома (docker-compose 3) - PullRequest
0 голосов
/ 18 мая 2018

У меня есть несколько контейнеров для веб-приложения (nginx, gunicorn, postgres и узел для создания статических файлов из исходного кода и рендеринга на стороне сервера React).В Dockerfile для контейнера узла у меня есть два шага: сборка и запуск ( Dockerfile.node ).Он заканчивается двумя каталогами внутри контейнера: bundle_client - это статический элемент для nginx и bundle_server - он используется в самом контейнере узла для запуска экспресс-сервера.

Затем мне нужно поделитьсявстроенная статическая папка (bundle_client) с контейнером nginx.Для этого в соответствии с указанием docker-compose в моем docker-compose.yml у меня есть следующие службы (см. Полный docker-compose.yml ):

node:
  volumes:
    - vnode:/usr/src

nginx:
  volumes:
    - vnode:/var/www/tg/static
  depends_on:
    - node

и тома:

volumes:
  vnode:

Запуск docker-compose build завершается без ошибок.Выполнение docker-compose up запускает все нормально, и я могу открыть localhost:80, и nginx, gunicorn и node Express SSR все работают отлично, и я вижу веб-страницу, но все статические файлы возвращают ошибку 404. Не найдено.

Если я проверяю тома с помощью docker volume ls, я вижу два вновь созданных тома с именами tg_vnode (которые мы здесь рассматриваем) и tg_vdata (см. Полный docker-compose.yml)

Если я зайду в nginxконтейнер с docker run -ti -v /tmp:/tmp tg_node /bin/bash Я не вижу свою папку www/tg/static, которая должна сопоставлять мои статические файлы с тома узла.Также я попытался создать пустую папку /var/www/tg/static с контейнером nginx Dockerfile.nginx, но она осталась пустой.

Если я сопоставлю папку bundle_client с хост-машины в docker-compose.yml в nginx.volumesв разделе - ./client/bundle_client:/var/www/tg/static все работает нормально, и я вижу все статические файлы, обслуживаемые nginx, в браузере.

Что я делаю неправильно и как заставить мой контейнер делиться встроенным статическим контентом с контейнером nginx?

PS: Я прочитал все документы, все проблемы с github и stackoverflow Q & As, и, как я понял, это должно работать, и нет никакой информации, что делать, когда это не так.

UPD: Результат docker volume inspect vnode:

[
{
    "CreatedAt": "2018-05-18T12:24:38Z",
    "Driver": "local",
    "Labels": {
        "com.docker.compose.project": "tg",
        "com.docker.compose.version": "1.21.1",
        "com.docker.compose.volume": "vnode"
    },
    "Mountpoint": "/var/lib/docker/volumes/tg_vnode/_data",
    "Name": "tg_vnode",
    "Options": null,
    "Scope": "local"
}
]

Файлы: Dockerfile.node , docker-compose.yml

Nginx dockerfile: Dockerfile.nginx


UPD: Я создал упрощенное хранилище для воспроизведения вопроса: repo (есть некоторые предупреждения на npm install, не смотря на то, что он устанавливается и собирается нормально).В конце концов, когда мы открываем localhost:80, мы видим пустую страницу и 404 сообщения для статических файлов (vendor.js и app.js) в инструментах разработчика Chrome, но должно быть сообщение React app: static loaded, сгенерированное сценарием реагирования.

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Два изменения, которые вам нужны.В вашем сервисе узла добавьте том типа

volumes:
  - vnode:/usr/src/bundle_client

Так как вы хотите поделиться /usr/src/bundle_client, вам НЕ следует использовать /usr/src/, потому что это разделит всю папку и структуру тоже.

А затем в вашем сервисе nginx добавьте том, например

volumes:
  - type: volume
    source: vnode
    target: /var/www/test/static
    volume:
      nocopy: true

. nocopy: true не дает нам понять, что на исходной карте контейнера содержимое сопоставленной папки не должно копироваться.И по умолчанию первый контейнер, который будет сопоставлен с томом, получит содержимое сопоставленной папки.В вашем случае вы хотите, чтобы это был контейнер node.

Также перед тестированием убедитесь, что вы выполнили команду ниже для уничтожения кэшированных томов

docker-compose down -v

Вы можете видеть во время моего тестаКонтейнер имел файлы

Nginx has files

0 голосов
/ 21 мая 2018

Объяснение того, что происходит, шаг за шагом

Dockerfile.node

    ...
    COPY ./client /usr/src
    ...

docker-compose.yml

services:
  ...
  node:
    ...
    volumes:
      - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
      - vnode:/usr/src
  ...
volumes:
  vnode:
  1. docker-compose up создает сэтот Dockerfile.node и docker-compose раздел именованный том с данными, сохраненными в /usr/src.

Dockerfile.nginx

FROM nginx:latest

COPY ./server/nginx.conf /etc/nginx/nginx.conf

RUN mkdir -p /var/www/tg/static

EXPOSE 80
EXPOSE 443

CMD ["nginx", "-g", "daemon off;"]
Это приводит к тому, что контейнеры nginx, созданные с помощью docker-compose, будут иметь пустой /var/www/tg/static/

docker-compose.yml

 ...
 nginx:
    build:
      context: .
      dockerfile: ./Dockerfile.nginx
    container_name: tg_nginx
    restart: always
    volumes:
      - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
      - vnode:/var/www/tg/static
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - node
      - gunicorn
    networks:
      - nw_web_tg

 volumes:
   vdata:
   vnode:
docker-compose up выдаст, что vnode именованный том создан и заполнен данными от /var/www/tg/static (пока пусто) до существующего vnode.

Итак, на этом этапе - nginxконтейнер имеет / var / www / tg / static empty, потому что он был создан пустым (см. mkdir в Dockerfile.nginx) - контейнер узла имеет / usr / src dir с клиентским файлом (смотрите, что было скопировано в Dockerfile.node) - vnode имеет содержимоеиз / usr / src из node и /var/www/tg/static из nginx.

Определенно, для передачи данных из / usr / src из вашего node контейнера в /var/www/tg/static в nginx контейнеревам нужно сделать что-то не очень приятное, потому что Docker еще не разработал другой способ: вам нужно объединить именованный том в исходной папке с связать том в месте назначения:

 nginx:
     build:
       context: .
       dockerfile: ./Dockerfile.nginx
     container_name: tg_nginx
     restart: always
     volumes:
       - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
       - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static
     ports:
       - "80:80"
       - "443:443"
     depends_on:
       - node
       - gunicorn
     networks:
       - nw_web_tg

Просто измените в docker-compose - vnode:/var/www/tg/static на - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static

...