You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

docker-compose中API容器无法被同编排其他容器访问如何解决

问题原因

你遇到的连接拒绝问题是Docker Compose部署微服务/测试任务的典型问题,核心诱因有两个:

  1. Flask默认监听地址限制:Flask框架flask run命令默认只绑定容器内部回环地址127.0.0.1,此时只有容器内部的本地进程能访问5000端口,同网络的其他容器无法通过容器虚拟网卡访问该端口。你在宿主机能curl通通常是在API容器启动较长时间后操作,不排除手动测试时Flask已完成加载,但容器间访问时因监听地址限制直接被拒绝。
  2. depends_on不等待服务就绪:Docker Compose的depends_on配置仅控制容器的启动先后顺序,不会等待容器内的应用完成初始化、开始监听端口。你的测试容器启动后会立刻执行Python脚本发请求,此时Flask很可能还在加载依赖、初始化进程,没有开始监听5000端口,直接触发连接拒绝。
  3. 低概率诱因:你使用了自定义外部网络,若网络配置存在子网冲突、DNS解析失效,也会导致连通性异常。
修复步骤

按顺序操作即可解决问题:

1. 修正Flask启动监听地址

修改你的API镜像启动命令,让Flask监听容器所有网卡地址,不要只绑定回环地址:

  • 如果用flask run直接启动,启动命令改为:
    flask run --host=0.0.0.0 --port=5000
    
  • 如果用gunicorn/uwsgi等生产级WSGI服务器启动,绑定地址改为0.0.0.0:5000,示例:
    gunicorn --bind 0.0.0.0:5000 app:app
    

修改后重启API容器,可进入API容器执行ss -tulpn | grep 5000验证,输出中如果出现0.0.0.0:5000的监听记录就说明配置正确。

2. 增加服务就绪等待逻辑

两种方案选其一即可,优先选第一种,适配性更强:

方案一:测试脚本增加重试逻辑

修改你的Python测试脚本,在正式发测试请求前先循环探测API端口状态,等服务真正就绪后再跑测试用例,改后代码示例:

import os
import requests
import time

api_address = 'my_api'
api_port = 5000
max_retry = 15
retry_wait = 2

# 等待API服务就绪
for attempt in range(max_retry):
    try:
        # 只要端口有响应就说明服务已启动,返回404属于无根路由的正常情况
        probe = requests.get(f"http://{api_address}:{api_port}/", timeout=2)
        if probe.status_code in [200, 404]:
            break
    except requests.exceptions.ConnectionError:
        print(f"API未就绪,{retry_wait}秒后重试,剩余重试次数:{max_retry - attempt -1}")
        time.sleep(retry_wait)
else:
    raise ConnectionError("等待API服务超时,无法建立连接")

# 原有测试逻辑
r = requests.get(
    url='http://{address}:{port}/Authorization'.format(address=api_address, port=api_port),
    headers= {
        'Authorization': 'alice=wonderland'
        }
)

output = '''
============================
    Authentication test
============================

request done at "/Authorization"
| username="alice"
| password="wonderland"

expected result = 200
actual restult = {status_code}

==>  {test_status}

'''

status_code = r.status_code

if status_code == 200:
    test_status = 'SUCCESS'
else:
    test_status = 'FAILURE'
print(output.format(status_code=status_code, test_status=test_status))

方案二:Compose配置健康检查依赖

如果不想修改测试代码,可以给API服务加健康检查配置,让Compose等API服务真正健康后再启动测试容器,注意该特性需要Docker Compose v2.1+版本支持,修改docker-compose.yml对应服务配置:

services:
  api:
    image: my_api
    container_name: my_api
    networks:
      app_subnet :
        ipv4_address: 172.16.0.10
    ports:
      - "5000:5000"
    # 新增健康检查配置
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/"]
      interval: 2s
      timeout: 2s
      retries: 5
      start_period: 3s

  authentication:
    image: authentication
    # 修改depends_on规则,等待API服务健康再启动
    depends_on:
      api:
        condition: service_healthy
    container_name: authentication_test
    networks:
      - app_subnet 
    volumes:
      - /home/oussama/Downloads/projet2/:/home/

注意用这个方案需要保证你的API镜像内预装了curl命令,如果没有可以把探测命令换成wget或者Python单行命令探活。

3. 网络连通性验证

如果改完前两步还是有问题,执行以下操作排查网络:

  • 先确认外部网络app_subnet存在,执行docker network ls | grep app_subnet,如果不存在先手动创建:docker network create --subnet=172.16.0.0/24 app_subnet
  • 两个容器启动后,进入测试容器执行ping my_api,看能不能正常解析到IP、ping通,如果解析失败可以先去掉固定IP配置,直接使用Compose服务名api作为访问地址,Compose内置DNS会自动解析服务名到对应容器IP。
  • 进入测试容器后直接执行curl -v http://my_api:5000/Authorization看具体报错,根据报错调整即可。

内容的提问来源于stack exchange,提问作者oussama benbelhassen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:09:19