another_dream
@another_dream
Backend-разработчик, Laravel/ZF2/Yii2

Как настроить коммуникацию между двумя Docker Compose проектами на одной машине по HTTP?

Имеется два Docker Compose проекта, развёрнуты локально под Windows.
Оба проекта имеют свои хосты, допустим: front.local и api.local, хосты локальные, прописаны в etc/hosts.
Оба проекта содержат контейнеры с PHP и Nginx.

Как мне со стороны front-проекта заиметь возможность делать http-запросы на api-проект?
Ожидаю что-то вроде типичного file_get_contents('http://api.local') (PHP) со стороны front, однако, этот адрес не резолвится, как я понимаю.
Куда копать и как реализовать требуемую связь?

Спасибо.
  • Вопрос задан
  • 1556 просмотров
Решения вопроса 1
another_dream
@another_dream Автор вопроса
Backend-разработчик, Laravel/ZF2/Yii2
Реализовать задуманное можно с помощью прокси.
В самом примитивном варианте это будет что-то вроде nginx-proxy.
Можно так же использовать Traefik, но с ним не задалось, так как почему-то всегда один из хостов поставлялся с авто-балансировкой в зависимости от того, какой компоуз был поднят первым (если api, то api.local отвечал всегда с нужного сервиса, а front.local постоянно переключался то на api, то на front сервис, балансируя между ними), проблему не смог решить и пошёл более простым способом -- воспользовался nginx-proxy.
Если кто знает как правильно сконфигурировать Traefik, чтобы не возникло этой проблемы с балансировкой -- отпишите в комментарии.

Nginx Proxy запускается так же в Докере, как контейнер, можно через docker-compose:
version: '3'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

networks:
  proxy:
    driver: bridge
# вне этого docker-compose.yml сеть будет доступна по имени {директория}_proxy, в моём случае это nginx_proxy


Конфигурация Docker Compose для хостов (описано только самое важное):
# ...
services:
  # Web server
  web:
    image: nginx
    environment:
      - 'VIRTUAL_HOST=${NGINX_HOST}' # подтягиваем из конфигурации окружения (.env, NGINX_HOST=api.local)
    networks:
       nginx_proxy: # чтобы наш хостовый nginx мог достучаться по общей с прокси сети до других контейнеров в той же сети
           aliases:
               - ${NGINX_HOST} # указываем алиас, по которому будет доступен контейнер, в моём случае это локальный хост api.local
       default: # дефолтная сеть, чтобы не ломать связь внутри текущей Docker Compose конфигурации

  # PHP
  php:
    image: php
    networks:
      - nginx_proxy # возможность из PHP иметь доступ к общей прокси сети, чтобы взаимодействовать с другими хостами
      - default

networks:
  nginx_proxy: # возьмём сеть извне
    external: true

Примерно повторяем конфигурирование для front-сервиса.
Сначала стартуем прокси, потом уже хосты.
Теперь хост front.local может обратиться к api.local по имени хоста (например, curl или file_get_contents('http://api.local/')).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@grinat
Докер по умолчанию все на один и тот же ip вешает, например на 192.168.99.100 надо просто разные порты в композе прописать и все. Эти же ip с портами в хост файле. Т.е.
back:
version: '2'
services:
nginx:
ports:
- "4001:80"
front:
version: '2'
services:
nginx:
image: nginx:stable-alpine
ports:
- "4002:80"
Если есть проблемы, то подыми nginx и там проксируй:
server {
client_max_body_size 0;
listen 80;
server_name front;

location / {
client_max_body_size 0;
proxy_pass http://192.168.99.100:4001;
}

server {
client_max_body_size 0;
listen 80;
server_name back;

location / {
client_max_body_size 0;
proxy_pass http://192.168.99.100:40012;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы