为什么无法从Docker容器内部访问部署的Flask服务?
问题根因
Docker容器默认拥有独立的网络命名空间,你在客户端代码中写的http://localhost:5000指向的是客户端容器自身的5000端口,而你的Flask服务运行在另一个独立的服务端容器内,客户端容器的5000端口没有任何服务监听,因此会抛出连接拒绝报错。
你在宿主机能正常访问是因为启动服务端容器时加了-p 5000:5000端口映射,把宿主机的5000端口绑定到了服务端容器的5000端口,因此宿主机层面的localhost:5000可以转发到服务端容器。直接填写服务端容器的动态内网IP可访问是因为两个容器默认都挂载在docker0网桥下,同网段可直接通信,但容器内网IP是动态分配的,重启后会变化,不适合硬编码使用。
可行解决方案
方案1:客户端容器共享宿主机网络
启动客户端容器时添加--network host参数,客户端容器会直接复用宿主机的网络栈,此时代码中的localhost:5000和宿主机访问逻辑完全一致,可直接连通:
docker run --network host client
该方案无需修改代码,适合本地快速测试使用。
方案2:自定义Docker网络,用容器名做域名访问
这是多容器部署的标准实现,稳定性更高:
- 先创建自定义网桥网络
docker network create app-network
- 启动服务端容器时加入该网络,并指定容器名
docker run -p 5000:5000 --network app-network --name flask-server server
- 修改客户端代码的请求地址,将
localhost替换为服务端的容器名
import requests response = requests.get("http://flask-server:5000/") print(response.text)
- 重新构建客户端镜像后,加入同一个网络启动即可
docker run --network app-network client
Docker自定义网桥自带内部DNS解析能力,同一网络下的容器可直接通过容器名互相访问,不受容器重启、IP变动的影响。
方案3:使用宿主机局域网IP
如果不想修改网络配置,也可以将客户端代码中的localhost替换为宿主机的局域网IP(比如192.168.1.100这类),依托已经配置的端口映射完成访问,但该方案依赖宿主机IP的稳定性,换环境后需要同步修改代码。
内容的提问来源于stack exchange,提问作者Emperor Palpatine
相关产品推荐
相关产品推荐

