NGINX docker-compose — Host не найден в восходящем nuxt: 3000

#django #docker #nginx #amazon-ec2 #docker-compose

#django #docker #nginx #amazon-ec2 #docker-compose

Вопрос:

Я пытаюсь настроить развернутое приложение на экземпляре EC2, я не могу получить доступ к приложению, когда оно подключено к общедоступному IP-адресу ec2. Я проверил группы безопасности и разрешил весь входящий трафик на порты, просто чтобы посмотреть, смогу ли я попасть на домашнюю страницу или страницу администратора django.

Допустим, мой IP-адрес ec2 равен 34.245.202.112, как мне сопоставить мое приложение, чтобы nginx обслуживал

Интерфейс (nuxt) в 34.245.202.112

Серверная часть (django) в 34.245.202.112/admin

API (DRF) в 34.245.202.112 /api

Когда я пытаюсь это сделать, ошибка, которую я получаю от nginx, выглядит так

nginx | 2020-11-14T14:15:35.511973183Z 2020/11/14 14:15:35 [emerg] 1#1: host not found in upstream "nuxt:3000" in /etc/nginx/conf.d/autobets_nginx.conf:9

Это моя конфигурация

docker-compose

версия: «3.4»

 services:
db:
    restart: always
    image: postgres
    volumes:
    - pgdata:/var/lib/postgresql/data
    environment:
    - POSTGRES_USER=postgres
    - POSTGRES_PASSWORD=postgres
    ports:
    - "5432:5432"
    expose:
    - 5432
    networks:
    - random_name

django:
    container_name: django
    build:    
    context: ./backend
    env_file: .env
    environment:
    - DEBUG=True
    command: >
    sh -c "./wait-for-it.sh db:5432 amp;amp; 
            ./autobets/manage.py collectstatic --no-input amp;amp;
            ./autobets/manage.py makemigrations amp;amp;
            ./autobets/manage.py migrate --no-input amp;amp;
            ./autobets/manage.py runserver_plus 0.0.0.0:8001
            "
    - "8001"
    volumes:
    - ./backend:/app
    depends_on:
    - db
    restart: on-failure

nginx:
    image: nginx
    container_name: nginx
    ports:
    - "80:80"
    restart: always
    depends_on:
    - nuxt
    - django
    volumes:
    - ./nginx/conf:/etc/nginx/conf.d
    - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
    - ./backend/static:/static
    networks:
    - random_name

nuxt:
    build:
    context: ./frontend
    environment:
    - API_URI=http://django:8001/api

    command: sh -c "npm install amp;amp; npm run dev"
    volumes:
    - ./frontend:/app
    ports:
    - "3000:3000"
    depends_on:
    - django
    networks:
    - random_name

volumes:
pgdata:
networks:
random_name:
  

nginx.conf

 # the upstream component nginx needs to connect to
upstream django {
    ip_hash;
    server django:8001;
}

upstream nuxt {
ip_hash;
server nuxt:3000;
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name 34.245.202.112; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    location /static/ {
        alias /static/;
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        proxy_pass  django;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Host $host;
    }
}
  

Комментарии:

1. Ваша конфигурация nginx не будет работать, даже если вы исправите эту ошибку. Оба proxy_pass и uwsgi_pass являются обработчиками содержимого . У вас не может быть более одного обработчика содержимого в одном местоположении.

2. @IvanShatsky Я исправил это сейчас, но все равно получаю ту же ошибку. Знаете ли вы хороший шаблон конфигурации, который я могу использовать для справки?

Ответ №1:

Посмотрите на этот минимальный пример:

 server {
  listen 80;
  listen 8000;  # from you config, remove if unnecessary

  server_name 34.245.202.112;

  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-Host $host;

  location / {
    # 'the frontend(nuxt) at 34.245.202.112'
    # This is the default route. Requests get here when there's no
    # better match to go.
    proxy_pass http://nuxt:3000;
  }

  location /api/ {
    # This location will trigger when location in URI begins with '/api/'
    # e.g. http://yourserver.org/api/v1/hello/world
    proxy_pass http://django:8001;
  }

  location /admin/ {
    # exactly as /api/
    proxy_pass http://django:8001;
  }

  location /static/ {
    # same as /api/ but local files instead of proxy
    alias /static/;
  }
}
  

Как видно из примера, каждое местоположение имеет префикс URI. NGINX проверит все эти «префиксы» на соответствие местоположению во входящих HTTP-запросах, найдя наилучшее соответствие. Как только найдено наилучшее совпадение, NGINX сделает все, что вы написали внутри блока. В приведенном выше примере все запросы, начинающиеся с /api/ или /django/ , отправляются на django серверную часть. Запросы, начинающиеся с /static/ , обслуживаются из локальных файлов. Все остальное отправляется на nuxt серверную часть.

Я не уверен, правильно ли я понял ваши намерения, возможно, потому, что мне не хватает оригинальной конфигурации, которую вы отредактировали, поэтому вам нужно выбрать отсюда. Просто помните, что вы не ограничены префиксами URI для местоположений (вы можете использовать регулярное выражение или точное совпадение) и что вы можете создавать вложенные местоположения. Ознакомьтесь с этим замечательным руководством для начинающих от NGINX для получения дополнительной информации http://nginx.org/en/docs/beginners_guide.html .

ОБНОВЛЕНИЕ: Посмотрев на другие ответы здесь, я подумал, что должен ответить на вопрос в заголовке, а не просто на базовую конфигурацию. Причина, по которой вы получили host not found in upstream ошибку, заключается в том, что вы не указали resolver директиву. Это необходимо при использовании DNS-имен в upstream блоках, а для NGINX в Docker вы можете использовать это: resolver 127.0.0.11 ipv6=off; . Поместите его в http блок, который находится за пределами server блока.

‘127.0.0.11’ — это DNS-сервер Docker. Он разрешает имена служб и контейнеров, а также «обычные» записи DNS (для этого используется конфигурация DNS хоста). Вам не нужно назначать псевдоним службе или устанавливать container_name , поскольку имя службы само по себе является записью DNS. Он разрешается для всех контейнеров этой службы. resolver В базовой конфигурации, которую я опубликовал, использование не было необходимым, потому что я не использовал upstream блоки.

Ответ №2:

Вам не хватает alias раздела в вашем network блоке файла docker-compose. Определенные вами псевдонимы автоматически обновят /etc/hosts файл контейнеров, и, следовательно, ваш контейнер nginx будет знать о nuxt хосте.

 services:
  nuxt:
    networks:
      some-network:
        aliases:
          - nuxt
  

дополнительная информация здесь. ctrl-f для псевдонимов: https://docs.docker.com/compose/compose-file /

Комментарии:

1. будет ли использование driver: bridge делать то же самое?

2. Основываясь на моем локальном тестировании, вы не можете определить оба network_mode и networks в service блоке. И мой тест с just network_mode: bridge не разрешил хост правильно.

3. Имена служб (nuxt, django, db и т. Д.) По умолчанию Становятся DNS-именами. Разрешение имени службы внутри контейнера приведет к получению списка IP-адресов всех контейнеров, принадлежащих этой службе. Я не понимаю, как здесь может помочь псевдоним.

Ответ №3:

Имя контейнера «nuxt» не определено в файле docker-compose, поэтому имя хоста не может быть разрешено контейнером nginx. Попробуйте исправить ошибку nginx, добавив container_name:nuxt в службу nuxt в файле docker-compose.