NGINX docker-compose - 在上游 nuxt:3000 中找不到主机

Posted

技术标签:

【中文标题】NGINX docker-compose - 在上游 nuxt:3000 中找不到主机【英文标题】:NGINX docker-compose - Host not found in upstream nuxt:3000 【发布时间】:2021-02-26 06:58:03 【问题描述】:

我正在尝试在无法访问的 EC2 实例上配置已部署的应用程序 应用程序在 ec2 公共 IP 上启动时。我检查了安全组并允许所有 到端口的入站流量只是为了查看我是否可以访问 django 的主页或管理页面。

假设我的 ec2 IP 地址是 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 && 
            ./autobets/manage.py collectstatic --no-input &&
            ./autobets/manage.py makemigrations &&
            ./autobets/manage.py migrate --no-input &&
            ./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 && 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;
    

【问题讨论】:

即使你修复了那个错误,你的 nginx 配置也不会工作。 proxy_passuwsgi_pass 都是 内容处理程序。一个位置内不能有多个内容处理程序。 @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 指令。在 upstream 块中使用 DNS 名称时有必要,对于 Docker 中的 NGINX,您可以使用:resolver 127.0.0.11 ipv6=off;。将其放在http 块中,即server 块之外。

'127.0.0.11' 是 Docker DNS。它解析服务和容器名称以及“正常”DNS 记录(因为这是使用主机的 DNS 配置)。您不必为服务分配别名或设置 container_name,因为服务名称本身就是 DNS 记录。它解析为该服务的所有容器。在我发布的基本配置中没有必要使用resolver,因为我没有使用upstream 块。

【讨论】:

【参考方案2】:

您在 docker-compose 文件的 network 块中缺少 alias 部分。您定义的别名将自动更新容器的 /etc/hosts 文件,因此您的 nginx 容器将知道 nuxt 主机。

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

更多信息在这里。 ctrl-f 别名:https://docs.docker.com/compose/compose-file/

【讨论】:

会使用 driver: bridge 做同样的事情吗? 根据我的本地测试,您不能在 service 块中同时定义 network_modenetworks。而且我只用network_mode: bridge 进行的测试没有正确解析主机。 服务名称(nuxt、django、db等)默认成为DNS名称。解析容器内的服务名称将生成属于该服务的所有容器的 IP 地址列表。我看不出别名在这里有什么帮助。【参考方案3】:

docker-compose 文件中没有定义容器名称“nuxt”,因此 nginx 容器无法解析主机名。 尝试通过在 docker-compose 文件中的 nuxt 服务中添加 container_name:nuxt 来修复 nginx 错误。

【讨论】:

以上是关于NGINX docker-compose - 在上游 nuxt:3000 中找不到主机的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose 简单搭建nginx的ssl环境

docker-compose运行nginx

docker-compose快速启动nginx

通过 Nginx (Django/React/Nginx/Docker-Compose) 提供 Django 媒体文件

docker-compose部署nginx

Docker-compose实现nginx反向代理