Docker-Compose启动时Nginx报upstream api:5000主机未找到问题求助
我花了好几个小时排查这个问题,还是没找到根源。下面是我的相关配置和报错信息,希望能得到帮助:
相关配置文件
docker-compose.yml
version: "3" services: postgres: image: "postgres:latest" environment: - POSTGRES_PASSWORD=postgres_password redis: image: "redis:latest" nginx: restart: always build: dockerfile: Dockerfile context: ./nginx ports: - '3666:80' depends_on: - api - client api: build: dockerfile: Dockerfile.dev context: ./server volumes: - /app/node_modules - ./server:/app environment: - REDIS_HOST=redis - REDIS_PORT=6379 - PGUSER=postgres - PGHOST=postgres - PGDATABASE=postgres - PGPASSWORD=postgres_password - PGPORT=5432 client: stdin_open: true build: dockerfile: Dockerfile.dev context: ./client volumes: - /app/node_modules - ./client:/app worker: build: dockerfile: Dockerfile.dev context: ./worker volumes: - /app/node_modules - ./worker:/app
Nginx default.conf
upstream client { server client:3000; } upstream api { server api:5000; } server { listen 80; location / { proxy_pass http://client; } location /api { rewrite /api/(.*) /$1 break; proxy_pass http://api } }
报错信息
执行docker-compose up --build时出现以下错误:
nginx_1 | nginx: [emerg] host not found in upstream "api:5000" in /etc/nginx/conf.d/default.conf:6
问题分析与解决方案
嘿,我一眼就看到了一个明显的语法错误,这大概率是你当前问题的核心原因:
Nginx配置语法错误(最关键)
看你的default.conf里的proxy_pass http://api这一行,末尾少了分号!Nginx对语法要求很严格,缺少分号会导致配置解析失败,进而触发类似“找不到上游主机”的错误。把这行改成:proxy_pass http://api;这一步先搞定,应该能解决大部分问题。
容器启动顺序的潜在问题
虽然你在nginx服务里加了depends_on,但这个指令只是保证nginx在api和client之后启动,不保证api服务已经完全就绪。如果api服务启动较慢(比如依赖数据库初始化),Nginx启动时api容器可能还没完成服务启动,也会抛出类似错误。如果修复语法后还是有问题,可以试试给Nginx加个启动前的等待逻辑:- 下载
wait-for-it.sh脚本到nginx目录 - 修改Nginx的Dockerfile:
FROM nginx:alpine COPY wait-for-it.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/wait-for-it.sh COPY default.conf /etc/nginx/conf.d/ CMD ["wait-for-it.sh", "api:5000", "--", "nginx", "-g", "daemon off;"]
这样Nginx会等到api的5000端口就绪后再启动。
- 下载
验证api服务端口
确保你的api服务确实在监听5000端口——docker-compose里不需要暴露端口(ports指令),因为容器间通信可以直接用服务名+内部端口,只要api服务本身配置的是5000端口就行。
先优先修复语法错误,重新构建启动试试,应该能解决当前的报错。如果还有问题,再排查启动顺序的问题。
内容的提问来源于stack exchange,提问作者GurbaniX

