Docker Compose容器间可Ping但Curl失败,端口映射疑问求助
问题描述
部署了三个Docker容器:Node-Express应用、Python Fast-API应用和opencpu容器,遇到以下问题:
- Node-Express容器可通过服务名与opencpu容器通信,curl能正常获取数据,但无法向Python容器发送GET/POST请求
- 浏览器通过
localhost:9000可正常访问Python应用,Node-Express容器能通过服务名ping通Python容器,但执行curl时报错:curl: (7) Failed to connect to pythonapi port 80: Connection refused - 当curl命令指定端口8000时请求成功;docker-compose.yml中配置的是宿主机9000映射到容器内8000,容器间通信必须用8000,而访问opencpu容器无需指定端口,对此存在疑问
配置文件展示
Node-Express Dockerfile
FROM node:12-slim WORKDIR /starter ENV NODE_ENV development COPY package.json /starter/package.jso RUN npm install RUN apt-get update && apt install nano COPY .env.example /starter/.env.example COPY . /starter CMD ["ls"] CMD ["npm", "run", "start"]
Opencpu Dockerfile
from opencpu/ubuntu-18.04
Python Dockerfile
FROM python:3.9 WORKDIR /this-app RUN mkdir app # COPY ./app ./app COPY ./app/requirements.txt ./app WORKDIR /this-app/app RUN pip install -r requirements.txt WORKDIR ../ COPY ./app/models ./models COPY ./app/controllers.py . COPY ./app/main.py . CMD ["python", "./main.py"] EXPOSE 8000
Docker Compose 文件
version: '3' services: web: build: ./web ports: - "8012:8080" opencpu: image: opencpu container_name: opencpu build: context: ./R dockerfile: dockerfile ports: - 8014:8004 python-api: image: python-api build: context: ./python dockerfile: dockerfile ports: - 9000:8000
问题分析与解决
1. 容器间通信端口差异的核心原因
- 容器间通信用内部端口:Docker容器之间的通信基于内部网络,端口映射(如
9000:8000)仅用于宿主机外部访问,容器间必须使用容器内部服务监听的端口(此处Python容器内部是8000),与宿主机映射端口无关。 - opencpu无需指定端口的原因:opencpu官方镜像默认监听80端口(HTTP默认端口),curl未指定端口时会默认使用80,刚好匹配容器内部监听端口;而你的Python FastAPI应用默认监听8000端口,不是HTTP默认的80,因此必须显式指定端口。
2. curl连接拒绝的直接原因
当在Node容器中执行curl python-api时,curl默认用80端口发起请求,但Python容器内部没有服务监听80端口,因此触发连接拒绝错误;指定8000端口后,请求命中FastAPI的监听端口,所以请求成功。
3. 优化与修复方案
- 统一端口(可选):若想让Python容器也能无端口访问,可修改FastAPI启动配置,让其监听80端口。例如在
main.py中调整启动代码:
同时更新Dockerfile的# 原代码示例 # uvicorn.run("main:app", host="0.0.0.0", port=8000) # 修改为 uvicorn.run("main:app", host="0.0.0.0", port=80)EXPOSE 80,docker-compose端口映射改为9000:80,这样容器间用curl python-api即可直接访问,宿主机仍通过localhost:9000访问。 - 明确指定端口:保持现有配置,在Node-Express应用中请求Python服务时,显式指定8000端口,例如请求地址写为
http://python-api:8000/xxx。 - 修复docker-compose语法错误:原配置中
python-api服务定义后缺少冒号,会导致docker-compose解析失败,需补充冒号(已在上方配置文件中修正)。
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

