Docker部署Nginx与Django容器在AWS EC2上报host not found in upstream错误
问题根本原因
- 配置修改后服务名不匹配:你调整配置时将Django服务名从
my_server改为scrimmage,但Nginx配置中上游地址仍写my_server,Docker Compose内部DNS依赖服务名做域名解析,名称不一致直接导致解析失败。 - 端口映射逻辑错误:初始配置中Django容器内部监听8000端口,你修改端口映射为
8000:80的前提是Django镜像内部已改为监听80端口,如果镜像本身没有修改内部监听端口,该配置会直接导致Django服务无法正常访问。 - 启动顺序导致的偶发解析失败:
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
相关产品推荐
相关产品推荐

