You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker Compose:实现同一配置文件中容器的网络互通

解决Docker Compose中Flask容器互相通信的问题

嘿,这个问题我熟!Docker Compose 其实默认就给同个配置里的容器搭好了专属通信网络,咱们一步步把坑填上就行~

核心原理:Docker Compose默认网络

当你用docker-compose up启动服务时,它会自动创建一个以项目目录名为前缀的桥接网络(比如你的项目在my-flask-project目录,网络名就是my-flask-project_default)。所有在这个docker-compose.yaml里定义的服务,都会自动加入这个网络,并且:

  • 容器之间可以直接用服务名称作为主机名访问(不用记IP)
  • 通信时用容器内部暴露的端口,不需要依赖宿主机的端口映射(宿主机端口是给外部访问用的)

你可能踩的几个坑(以及解决办法)

1. Flask服务绑定了127.0.0.1,导致外部无法访问

这是最常见的问题!如果你的Flask代码里写的是app.run(port=5000),默认会绑定127.0.0.1——这意味着只有容器自己能访问这个服务,同一个网络的其他容器根本连不上。

修正代码:必须绑定0.0.0.0,允许所有IP访问:

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)  # 重点是host='0.0.0.0'

2. 用localhost或宿主机IP访问另一个容器

容器里的localhost指的是容器自己,不是宿主机也不是另一个容器!比如在service-b里访问http://localhost:5000,只会请求service-b自己的5000端口,而不是service-a的。

正确姿势:用docker-compose.yaml里定义的服务名作为主机名,比如你的service叫flask-a,就访问http://flask-a:5000

完整示例配置

docker-compose.yaml

version: '3.8'

services:
  flask-a:
    build: ./flask-a  # 指向你的flask-a项目目录(含Dockerfile)
    ports:
      - "5001:5000"  # 宿主机5001端口映射容器5000,给外部访问用
    # 无需手动指定网络,默认加入项目专属网络

  flask-b:
    build: ./flask-b
    ports:
      - "5002:5000"
    # 直接通过服务名访问flask-a:5000即可

Flask服务的Dockerfile(两个服务通用)

FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir flask requests  # 根据你的依赖调整
COPY . .

CMD ["python", "app.py"]

flask-a的app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello from Flask Service A!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

flask-b的app.py(调用flask-a)

from flask import Flask
import requests

app = Flask(__name__)

@app.route('/')
def call_flask_a():
    try:
        # 用服务名flask-a作为主机名,端口是容器内部的5000
        response = requests.get('http://flask-a:5000')
        return f"Flask B received: {response.text}"
    except Exception as e:
        return f"Failed to connect to Flask A: {str(e)}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

验证步骤

  1. 把上述文件放到对应目录,运行docker-compose up --build
  2. 打开浏览器访问http://localhost:5002,应该能看到Flask B返回的来自Flask A的内容
  3. 如果还是有问题,进入容器内部测试连通性:
    # 进入flask-b容器
    docker exec -it <你的flask-b容器ID> bash
    # ping flask-a,看能不能解析到IP
    ping flask-a
    # 用curl测试访问
    curl http://flask-a:5000
    

可选:自定义网络(非必须)

如果你想更灵活地管理网络,可以手动定义一个网络,然后让服务加入:

version: '3.8'

networks:
  flask-network:
    driver: bridge  # 默认就是bridge,可省略

services:
  flask-a:
    build: ./flask-a
    ports:
      - "5001:5000"
    networks:
      - flask-network

  flask-b:
    build: ./flask-b
    ports:
      - "5002:5000"
    networks:
      - flask-network

效果和默认网络完全一样,只是名字更清晰而已。

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

火山引擎 最新活动