容器网络与 loopback 限制
症状
注册 ML Backend 时填了 http://localhost:9090 或 http://127.0.0.1:9090,前端报 422 校验失败:
URL must not point to loopback (localhost / 127.0.0.1 / 0.0.0.0 / ::1).
Use the Docker bridge IP (172.17.0.1) or service DNS (e.g. grounded-sam2-backend) instead.或:早期版本注册成功,但 Celery worker 真正调用时连不上,日志显示 Connection refused。
根因
localhost 在容器内指向容器自身,不是宿主机。当 ML Backend 跑在宿主机或另一个 compose service 上时:
- 容器 A 的
localhost:9090≠ 宿主机localhost:9090 - 跨容器调用必须通过 Docker 网络(service DNS 或 bridge IP)
v0.9.8 在 MLBackendCreate.url / MLBackendUpdate.url 上加了 field_validator 直接拒绝 loopback,避免后期才在 worker 调用时炸出 ConnectionRefused。
修复 / 规避
| 场景 | 应填 URL |
|---|---|
| ML Backend 跑在同一个 docker-compose | http://<service-name>:<port>(例 http://grounded-sam2-backend:8001) |
| ML Backend 跑在宿主机本地进程 | http://172.17.0.1:<port>(Linux 默认 bridge 网关;macOS/Windows 用 host.docker.internal) |
| ML Backend 跑在另一台机器 | 该机器的 LAN IP / 公网域名 |
自检命令:
bash
# 从 worker 容器内 ping 目标 URL
docker exec ai-annotation-platform-celery-worker-1 \
curl -sf http://172.17.0.1:8001/health相关存储 host 配置
SAM 工作流里 worker 把 task 文件路径转换成 presigned URL 给 ML Backend 拉取(v0.9.4-phase1)。MinIO presigned URL 默认拼 MINIO_HOST,但 ML Backend 在另一个网络命名空间访问该 URL 时也面临同样的 loopback 问题,因此引入:
bash
ML_BACKEND_STORAGE_HOST=http://172.17.0.1:9000worker 在生成给 ML Backend 的 URL 时优先用这个变量替换 host。配置在 .env,参考 .env.example。
相关
- commit:
d41236bfeat(v0.9.8): URL validator 拒绝 loopback - commit:
c5eaf94feat(v0.9.4-phase1): ML_BACKEND_STORAGE_HOST 引入 - 代码:
apps/api/app/schemas/ml_backend.py(field_validator)