Docker Nginx容器启动失败:upstream 'web:8000'找不到主机
Nginx容器启动失败:upstream "web:8000" 无法解析的解决方法
问题背景
- 原Docker容器陷入重启循环,删除旧容器后重新创建同名Nginx镜像容器,新容器直接处于
exited状态无法启动 - 容器日志报错:
nginx: [emerg] host not found in upstream "web:8000" in /etc/nginx/conf.d/nginx.conf:2 - 无法进入已退出的容器编辑配置,本地
/etc/nginx/conf.d/nginx.conf文件为空,现有包含配置的文件为/etc/nginx/nginx.conf、/etc/nginx/sites-available/default、/etc/nginx/sites-available/limeguide.org - 站点此前运行正常,无手动更新操作突然无法连接;将端口从8080改为80后可显示Nginx默认页面,但项目业务容器仍无法正常运行(域名:limeguide.org)
现有docker-compose.yml配置
version: '3.7' services: web: build: context: .. dockerfile: docker/Dockerfile restart: always container_name: sozluk_backend command: gunicorn djdict.wsgi:application --bind 0.0.0.0:8000 --workers 4 volumes: - static_volume:/usr/src/app/static:rw - media_volume:/usr/src/app/media:rw expose: - 8000 env_file: - ../conf/django.env depends_on: - db nginx: build: context: .. dockerfile: docker/nginx/Dockerfile restart: always container_name: sozluk_nginx volumes: - static_volume:/home/app/web/static - media_volume:/home/app/web/media ports: - "80:8080" depends_on: - web db: image: postgres:15.4-alpine restart: always container_name: sozluk_db user: postgres env_file: - ../conf/postgres.env redis: image: redis:7.2-alpine restart: always container_name: sozluk_redis user: redis celery: env_file: - ../conf/django.env build: context: .. dockerfile: docker/Dockerfile restart: always container_name: sozluk_celery_worker command: celery -A djdict worker -l info volumes: - media_volume:/usr/src/app/media depends_on: - db - redis celery-beat: restart: always env_file: - ../conf/django.env volumes: - media_volume:/usr/src/app/media build: context: .. dockerfile: docker/Dockerfile container_name: sozluk_celery_beat command: celery -A djdict beat -l info depends_on: - db - redis volumes: static_volume: media_volume:
解决步骤
1. 编辑正确的Nginx配置文件
日志指向容器内的/etc/nginx/conf.d/nginx.conf,但本地该文件为空,说明你的Nginx镜像构建时是从站点专属配置文件复制的规则,需要编辑本地的/etc/nginx/sites-available/limeguide.org:
- 打开该文件,找到包含
web:8000的upstream配置段(或直接在proxy_pass引用的位置) - 添加Docker内置DNS解析配置,同时设置后端服务就绪前的重试逻辑:
# 若存在upstream段,添加resolver upstream web { server web:8000; resolver 127.0.0.11 valid=30s; # Docker内置DNS服务器地址,固定值 } server { # 其他站点配置... location / { proxy_pass http://web; # 后端未就绪时自动重试 proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; # 其他proxy相关配置... } } - 若配置中没有单独的upstream段,直接在
server块内添加resolver 127.0.0.11 valid=30s;即可
2. 修复Docker Compose的启动依赖问题
depends_on仅保证容器启动顺序,不确保后端服务(web)完全就绪,给Nginx添加启动前的等待逻辑:
- 修改
docker-compose.yml中的nginx服务配置,添加挂载本地配置目录(方便后续修改)和启动等待命令:nginx: build: context: .. dockerfile: docker/nginx/Dockerfile restart: always container_name: sozluk_nginx volumes: - static_volume:/home/app/web/static - media_volume:/home/app/web/media # 挂载本地站点配置到容器内对应路径 - /etc/nginx/sites-available/limeguide.org:/etc/nginx/sites-available/limeguide.org - /etc/nginx/sites-enabled:/etc/nginx/sites-enabled ports: - "80:8080" depends_on: - web # 等待web服务8000端口就绪后再启动Nginx command: /bin/sh -c "while ! nc -z web 8000; do sleep 1; done; nginx -g 'daemon off;'" - 若Nginx镜像中没有
nc工具,需要在docker/nginx/Dockerfile中添加安装命令:# 以Alpine镜像为例 RUN apk add --no-cache netcat-openbsd
3. 重新构建并启动服务
执行以下命令清理旧容器、重新构建镜像并启动服务:
docker-compose down docker-compose build --no-cache nginx docker-compose up -d
4. 验证修复效果
- 查看Nginx容器日志确认启动状态:
docker logs sozluk_nginx - 检查所有容器运行状态:
docker ps - 访问域名
limeguide.org验证站点业务是否正常
内容的提问来源于stack exchange,提问作者mrvciv
相关产品推荐
相关产品推荐

