Goodilla
@Goodilla
Разработчик/архитектор веб приложений

Как настроить мультиконтейнерное решение в Docker + Nginx (nodeproxy)?

Пытаюсь решить вопрос с мультикойнерной сборкой решения. Необходимо запустить веб приложение с gateway и 3 сервисами. К нему прилагается Postgre DB и PgAdmin для администрирования.

Cоздал docker-compose, контейнеры запускаются, база данных работает, в текущей конфигурации Nginx можно запустить PgAdmin.

Проблема: Контейнеры не видят друг друга, а также работа nginx (кроме pgadmin) вызывает вопросы, явные проблемы с настройкой конфига. Поиск решения и попытки самостоятельно решить задачу с nginx пока не дали результатов.

Возможно, кто-нибудь сталкивался с подобным решением и сможет помочь. Благодарю!
------------------------------------------------------------------------------------------------------------
Обвноление. Конечное решение. (обратите вниманиен на работу ваших сервисов, по каким портом они запускаются, это важно!)

version: '3'

services:
  app:
    build:
      context: ./app
      target: development
    tty: true
    working_dir: /opt/app
    volumes:
      - ./app:/opt/app
      - ./static:/opt/static
    env_file:
      - .env
    ports:
      - '8081:8081'
    depends_on:
      - gateway

  gateway:
    build:
      context: ./gateway
      target: development
    tty: true
    working_dir: /opt/gateway
    volumes:
      - ./gateway:/opt/gateway
      - ./static:/opt/static
    env_file:
      - .env
    environment:
      NODE_ENV: development
      ENVIRONMENT: development
    expose:
      - '80:3000'
    depends_on:
      - authservice
      - customerservice
      - feedservice
    links: 
      - "authservice:auth.be.io"
      - "customerservice:customer.be.io"
      - "feedservice:feed.be.io"

  authservice:
    build:
      context: ./auth_service
      target: development
    tty: true
    working_dir: /opt/authservice
    volumes:
      - ./auth_service:/opt/authservice
      - ./static:/opt/static
    env_file:
      - .env
    environment:
      NODE_ENV: development
      ENVIRONMENT: development
    expose:
      - '80:3001'
    depends_on:
      - db

  customerservice:
    build:
      context: ./customer_service
      target: development
    tty: true
    working_dir: /opt/customerservice
    volumes:
      - ./customer_service:/opt/customerservice
      - ./static:/opt/static
    env_file:
      - .env
    environment:
      NODE_ENV: development
      ENVIRONMENT: development
    expose:
      - '80:3002'
    depends_on:
      - db

  feedservice:
    build:
      context: ./feed_service
      target: development
    tty: true
    working_dir: /opt/feedservice
    volumes:
      - ./feed_service:/opt/feedservice
      - ./static:/opt/static
    env_file:
      - .env
    environment:
      NODE_ENV: development
      ENVIRONMENT: development
    expose:
      - '80:3003'
    depends_on:
      - db

  db:
    image: postgres:12-alpine
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - ./postgres:/var/lib/postgresql/data
    expose:
      - '5432'
    restart: always

  nginx:
    container_name: proxy_nginx
    depends_on:
      - app
      - gateway
      - authservice
      - customerservice
      - feedservice
      - db
      - pgadmin
    image: nginx:latest
    ports:
      - '80:80'
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - ./static:/var/www/static
    restart: always
    volumes_from:
      - app
      - gateway
      - authservice
      - customerservice
      - feedservice

  pgadmin:
    container_name: pgadmin
    depends_on:
      - db
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD}
    expose:
      - '80'
    restart: always

Nginx:
server {
  root /var/www;
  listen 80;
  gzip on;
  gzip_types text/plain application/xml text/css application/javascript;
  gzip_min_length 1000;
  client_max_body_size 0;

  add_header X-Created-By "Blaze";

  location / {
    try_files /static/$uri $uri @nodeproxy;
  }

  location @nodeproxy {
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 1m;
    proxy_connect_timeout 1m;

    proxy_pass http://app:8081;
  }

  location /gateway {
    proxy_set_header Host $http_host;
    proxy_pass http://gateway:3000/api;
  }

  location /pgadmin {
    proxy_set_header X-Script-Name /pgadmin;

    proxy_pass http://pgadmin;
    proxy_intercept_errors on;
    error_page 503 = @nodeproxy;
    error_page 502 = @nodeproxy;
  }
}
  • Вопрос задан
  • 162 просмотра
Решения вопроса 1
Goodilla
@Goodilla Автор вопроса
Разработчик/архитектор веб приложений
ky0, Valentin Barbolin Проблему нашёл, суммирую
- Валентин был прав, говоря об отсутсвии необходимости выводить порты для контейнеров. Также вопрос касательно Expose (проброса портов из контейнера в внеший мир) необходим только при условии наличия доступа с локалки (то есть если надо обратиться к контейнеру).
- Я слишком много внимания уделял конфигу, но не самому решению. В нём крылась основная проблема. Сервисы на NodeJS запускались под собсвенными портами (3000, 3001 и т.д.), а контейнер обращался к сервису по внутреннему IP:80, что соответсвенно выкидывало ошибку ERRCONNECT (то есть не мог найти адрес)

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

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

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

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