You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Nginx与Django容器在AWS EC2上报host not found in upstream错误

问题根本原因

  1. 配置修改后服务名不匹配:你调整配置时将Django服务名从my_server改为scrimmage,但Nginx配置中上游地址仍写my_server,Docker Compose内部DNS依赖服务名做域名解析,名称不一致直接导致解析失败。
  2. 端口映射逻辑错误:初始配置中Django容器内部监听8000端口,你修改端口映射为8000:80的前提是Django镜像内部已改为监听80端口,如果镜像本身没有修改内部监听端口,该配置会直接导致Django服务无法正常访问。
  3. 启动顺序导致的偶发解析失败:depends_on仅控制容器启动顺序,不会等待Django服务完全就绪。本地环境性能好,Django启动速度快于Nginx,不会触发问题;EC2实例性能偏低时,Nginx启动完成时Django还未注册内部DNS,就会抛出host not found错误。

排查步骤

  • 进入运行中的Nginx容器,执行ping <Django服务名>验证内部DNS解析是否正常,执行curl <Django服务名>:<内部端口>验证服务端口是否可达。
  • 检查Django镜像的启动日志,确认容器内部实际监听的端口是否和配置一致。

修复方案

建议回退到你本地可用的初始配置逻辑,仅新增健康检查控制启动顺序即可,无需随意修改服务名和端口配置:

1. 修正docker-compose.yml配置

version: '3.7'

services:
  my_server:
    image: user/image-app
    build:
      context: .
    env_file:
      - ./.env
    ports:
      - "8000:8000"
    # 新增健康检查,确认Django服务就绪
    healthcheck:
      # 以下命令二选一:如果Django有可用健康检查路由用第一行,否则用netcat检查端口
      test: ["CMD", "curl", "-f", "http://localhost:8000/health/"]
      # test: ["CMD", "nc", "-z", "localhost", "8000"]
      interval: 3s
      timeout: 10s
      retries: 5

  nginx:
    build: ./nginx
    image: user/image-nginx
    ports:
      - "80:80"
    depends_on:
      my_server:
        # 等Django健康检查通过后再启动Nginx
        condition: service_healthy

volumes:
  static:

2. 保留初始可用的Nginx配置

upstream django {
    server my_server:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://django;
        # 建议新增以下两项配置,避免Django无法获取真实请求信息
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

如果确实需要将Django服务名改为scrimmage,只需要将Nginx配置中的上游地址同步修改为server scrimmage:8000;即可,保持服务名和端口一致即可正常解析。

内容的提问来源于stack exchange,提问作者C. S. F. Junior

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:06:02