Как настроить использование нескольких контейнеров в Docker с использованием Nginx в качестве nodeproxy?

Как можно настроить мультиконтейнерное приложение, включающее веб-приложение с gateway и тремя сервисами, а также Postgre DB и PgAdmin для администрирования?
  • 7 февраля 2024 г. 15:50
Ответы на вопрос 2
Для настройки мультиконтейнерного приложения с использованием Docker и Nginx в качестве прокси вам понадобятся следующие шаги:

1. **Создайте Dockerfile для каждого сервиса**:
   Для каждого из ваших сервисов (веб-приложение, gateway, сервисы) необходимо создать соответствующие Dockerfile, которые будут содержать инструкции для создания образов контейнеров.

2. **Создайте Nginx конфигурацию**:
   Создайте конфигурационный файл Nginx (например, `nginx.conf`), в котором вы настроите прокси-сервер для перенаправления запросов на соответствующие контейнеры сервисов.

3. **Используйте Docker Compose**:
   Затем создайте файл `docker-compose.yml`, в котором вы определите все контейнеры, которые должны быть запущены, включая веб-приложения, gateway, сервисы, Postgre SQL, PgAdmin и Nginx. В этом файле указываются зависимости между контейнерами, сетевые настройки и параметры конфигурации.

Вот примерный план того, как может быть настроен файл `docker-compose.yml`:

```yaml
version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - webapp
      - gateway
      - service1
      - service2
      - service3
    networks:
      - my-network

  webapp:
    build: ./path_to_your_webapp
    networks:
      - my-network

  gateway:
    build: ./path_to_your_gateway
    networks:
      - my-network
  
  service1:
    build: ./path_to_your_service1
    networks:
      - my-network

  service2:
    build: ./path_to_your_service2
    networks:
      - my-network

  service3:
    build: ./path_to_your_service3
    networks:
      - my-network

  postgresdb:
    image: postgres:latest
    environment:
      POSTGRES_DB: yourdb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - my-network

  pgadmin:
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: [email protected]
      PGADMIN_DEFAULT_PASSWORD: root
    ports:
      - "5050:80"
    depends_on:
      - postgresdb
    networks:
      - my-network

volumes:
  pgdata:

networks:
  my-network:
    driver: bridge
```

В этом примере `./nginx.conf` должен быть путь к вашему файлу конфигурации Nginx, а `./path_to_your_*` указывает на пути к каталогам различных сервисов, в которых находятся соответствующие Dockerfile.

4. **Запуск Docker Compose**:
   После настройки файла `docker-compose.yml`, вы можете запустить все сервисы одной командой:

   ```bash
   docker-compose up -d
   ```

Эта команда создаст и запустит контейнеры согласно вашим настройкам в фоновом режиме.

5. **Настраивайте Nginx как reverse proxy**:
   В вашем `nginx.conf` файле вам нужно настроить блоки `server` для каждого сервиса. Пример простого конфигурационного файла для Nginx в контексте использования его в качестве reverse proxy может выглядеть так:

```nginx
http {
    upstream webapp {
        server webapp:80;
    }

    upstream gateway {
        server gateway:80;
    }

    #... Конфиг
ky0 , Valentin Barbolin Проблему нашёл, суммирую 
- Валентин был прав, говоря об отсутсвии необходимости выводить порты для контейнеров. Также вопрос касательно Expose (проброса портов из контейнера в внеший мир) необходим только при условии наличия доступа с локалки (то есть если надо обратиться к контейнеру).
- Я слишком много внимания уделял конфигу, но не самому решению. В нём крылась основная проблема. Сервисы на NodeJS запускались под собсвенными портами (3000, 3001 и т.д.), а контейнер обращался к сервису по внутреннему IP:80, что соответсвенно выкидывало ошибку ERRCONNECT (то есть не мог найти адрес)

По итогу:
- Поменял порты запуска сервисов на 80
- Для DEV среды оставил expose для всех сервисов (для проверки), кроме APP, для PROD всё убрал

Итог прикрепил к задаче, может кому-нибудь пригодится. Благодарю
Похожие вопросы