Docker环境下Nginx报upstream backend主机未找到的问题求助
Docker容器搭建问题:Nginx无法解析backend上游服务
尝试搭建包含Nginx、React前端、Django后端的Docker容器环境,启动时Nginx抛出如下错误:
[emerg] 1#1: host not found in upstream "backend:8000" in /etc/nginx/nginx.conf:11 nginx: [emerg] host not found in upstream "backend:8000" in /etc/nginx/nginx.conf:11
以下是相关配置文件:
docker-compose.yml 配置
version: '3' services: frontend: build: context: ./frontend dockerfile: Dockerfile.prod volumes: - frontend-data:/usr/share/nginx/html backend: build: context: . dockerfile: Dockerfile.prod environment: - DEBUG=0 - ALLOWED_HOSTS=nginx,localhost,127.0.0.1 - SECRET_KEY=django-Super-secret-key - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres volumes: - static_data:/vol/web depends_on: - db networks: - app-networks db: image: postgres:latest restart: always environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres volumes: - db-data:/var/lib/postgresql/data nginx: build: context: ./nginx dockerfile: Dockerfile.prod ports: - "80:80" volumes: - frontend-data:/usr/share/nginx/html/frontend - static_data:/vol/static depends_on: - frontend - backend networks: - app-networks networks: app-networks: driver: bridge volumes: db-data: frontend-data: static_data:
nginx.conf 配置
worker_processes 1; events { worker_connections 1024; } http { sendfile on; large_client_header_buffers 4 32k; upstream backend_servers { server backend:8000; } server { listen 80; server_name mysite.com; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; server_name mysite.com; ssl_certificate /etc/ssl/certs/my-site.crt; ssl_certificate_key /etc/ssl/private/my-site.key; # Static files location /static/ { alias /vol/static/; } location / { root /usr/share/nginx/html/frontend; try_files $uri $uri/ /index.html; } # Reverse proxy requests to the uWSGI server location /api { rewrite ^/api(.*) $1 break; uwsgi_pass backend_servers; include /etc/nginx/uwsgi_params; proxy_redirect off; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } # Proxy pass requests for /admin to the Django admin server location /admin { uwsgi_pass backend_servers; include /etc/nginx/uwsgi_params; proxy_redirect off; proxy_redirect off; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } client_max_body_size 3M; } }
问题原因及解决办法
核心原因
- 网络隔离问题:部分服务未加入统一网络,导致Nginx无法解析backend的域名
- Nginx启动时解析机制:Nginx默认在启动阶段解析上游服务器IP,若此时backend容器未完全启动或网络未连通,就会抛出找不到主机的错误
- backend端口监听配置:若backend仅监听容器内部的127.0.0.1,外部服务(包括Nginx)无法访问
具体修复步骤
1. 统一所有服务的网络
将frontend和db服务也加入app-networks,确保所有服务在同一网络下通信:
修改docker-compose.yml中对应服务的配置:
frontend: # ... 原有配置 ... networks: - app-networks db: # ... 原有配置 ... networks: - app-networks
2. 修改Nginx配置实现动态解析
添加Docker内置DNS服务器地址,并配置上游服务器动态解析,避免启动阶段依赖backend就绪:
修改nginx.conf的http和upstream部分:
http { # 添加Docker内置DNS解析器 resolver 127.0.0.11 valid=30s; sendfile on; large_client_header_buffers 4 32k; upstream backend_servers { # 添加resolve参数,让Nginx在请求时动态解析 server backend:8000 resolve; } # ... 原有配置 ... }
3. 确认backend端口监听配置
检查backend的Dockerfile.prod,确保服务监听容器的0.0.0.0地址(而非仅127.0.0.1),比如uWSGI的启动命令:
uwsgi --socket 0.0.0.0:8000 --module your_project.wsgi
4. 可选:确保Nginx等待backend就绪
若需要严格保证backend服务启动后再启动Nginx,可以使用wait-for-it脚本:
- 下载wait-for-it.sh脚本到nginx目录
- 修改nginx的Dockerfile.prod:
COPY wait-for-it.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/wait-for-it.sh CMD ["wait-for-it.sh", "backend:8000", "--", "nginx", "-g", "daemon off;"]
内容的提问来源于stack exchange,提问作者swamper
相关产品推荐
相关产品推荐

