news 2026/10/9 16:09:08

Blinko AI Provider 模型拉取 Docker 内网连通性测试方案详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Blinko AI Provider 模型拉取 Docker 内网连通性测试方案详解
  • 后端
  • 前端
  • 人工智能
  • 大模型
  • RAG
  • 知识库
  • 桌面应用

【免费下载链接】blinko

An open-source, self-hosted personal AI note tool prioritizing privacy, built using TypeScript .

项目地址:https://gitcode.com/gh_mirrors/bl/blinko
点击查看免费下载

本文以 Blinko 仓库中 test-docker 测试目录 的 README 为主干,系统讲解如何验证并复现"AI Provider 模型列表拉取"经由服务端代理、在 Docker 内部网络中正常工作的修复方案。你将掌握:该问题的成因(浏览器直连 Docker 内网主机名失败)、一键搭建的 Mock 测试环境(含 Mock OpenAI、PostgreSQL、Blinko 三个容器)、完整的 UI 验证步骤,以及从源码层面理解fetchProviderModels在 服务端路由、前端状态层 与 代理封装 中的真实调用链。

问题背景:浏览器直连 Docker 内网主机名为何失败

Blinko 支持对接 Ollama、OpenAI、Anthropic、Google、Azure、MiniMax、VoyageAI 以及任意 OpenAI 兼容协议的自建 Provider。在添加 Provider 时,用户可以点击"Fetch Models"按钮拉取该 Provider 支持的模型列表。

修复之前的实现存在一个关键缺陷:fetchProviderModels由浏览器直接发起 HTTP 请求。这意味着当用户自建的服务运行在 Docker 内部网络时,配置的 Base URL 形如http://ollama:11434这类Docker 内部主机名,浏览器所在的宿主机网络根本无法解析、访问该主机名,导致模型列表拉取必然失败。

本次修复的核心思路是:把模型拉取逻辑从浏览器端迁移到 Blinko 后端服务端。由 Blinko 服务端容器向目标 Provider 容器发起请求——由于两个容器同属一个 Docker bridge 网络,可以互相通过服务名通信,因此http://ollama:11434、http://mock-openai:8080/v1这类内网地址可以正常工作。

测试环境架构

test-docker目录提供了完整的可复现测试环境,核心编排文件为 docker-compose.test.yml,其中包含三个服务:

服务镜像作用健康检查
mock-openainode:20-alpine模拟 OpenAI 兼容的模型列表 APIwget --spider http://localhost:8080/models
postgrespostgres:15-alpineBlinko 依赖的数据库pg_isready -U blinko
blinkoblinkospace/blinko:latest被测的 Blinko 应用本体依赖上述两者 healthy 后启动

三者统一挂载到名为blinko-test-network的 bridge 网络中,这是整个测试成立的前提——Blinko 容器与 Mock OpenAI 容器在同一个 Docker 内部网络里,服务端才能通过服务名mock-openai互相访问。

关键配置点说明:

  • blinko服务的DATABASE_URL=postgresql://blinko:blinko@postgres:5432/blinko中数据库主机名直接使用服务名postgres,同样是内网通信的典型用法;
  • NEXTAUTH_SECRET=test-secret-key-for-testing与NEXTAUTH_URL=http://localhost:1111用于本地登录鉴权;
  • 宿主机端口映射为1111:1111,即浏览器通过http://localhost:1111访问 Blinko。

Mock OpenAI 服务实现

模拟服务源码位于 test-docker/mock-openai/server.js,它用 Node 原生http模块实现了一个极简的 OpenAI 兼容服务:

const models = { data: [ { id: 'gpt-4o', object: 'model' }, { id: 'gpt-4o-mini', object: 'model' }, { id: 'gpt-3.5-turbo', object: 'model' } ] };

服务监听0.0.0.0:8080,对GET /v1/models与GET /models两个路径返回上述 JSON 模型列表,并输出访问日志(方法 + URL与Returning model list...)。同时设置了宽松的 CORS 响应头(Access-Control-Allow-Origin: *、Access-Control-Allow-Headers: Authorization, Content-Type, api-key),以便在任何来源下都可被调用。

测试步骤:一键启动与验证

第一步:启动测试环境

cd test-docker docker-compose -f docker-compose.test.yml up -d

首次启动会拉取blinkospace/blinko:latest、postgres:15-alpine、node:20-alpine三个镜像,之后up -d可快速重建/恢复。

第二步:等待服务就绪

docker-compose -f docker-compose.test.yml ps

由于编排文件中为mock-openai与postgres配置了 healthcheck,并为blinko配置了depends_on ... condition: service_healthy,blinko只有在两个依赖服务通过健康检查后才会启动。因此等待所有服务状态显示为healthy即可进入下一步。

第三步:访问 Blinko

浏览器打开http://localhost:1111,完成本地登录(使用测试环境的NEXTAUTH_SECRET/NEXTAUTH_URL即可正常走鉴权流程)。

第四步:在 AI 设置中添加 Provider 并拉取模型

  1. 进入Settings > AI Settings;
  2. 添加一个新的 Provider:
    • Provider Type:选择OpenAI或Custom;
    • Base URL:http://mock-openai:8080/v1(注意:这是 Docker 内部服务名,而非localhost);
    • API Key:test-key(Mock 服务不校验 Key,任意值均可);
  3. 点击Fetch Models按钮;
  4. 预期结果:模型下拉列表中应出现 3 个模型:
    • gpt-4o
    • gpt-4o-mini
    • gpt-3.5-turbo

第五步:通过日志确认请求来自服务端

docker logs mock-openai

预期输出类似:

2024-XX-XX... - GET /v1/models Returning model list...

这条日志的关键意义在于:请求是Blinko 服务端容器发出的(GET /v1/models来自内网服务名解析),而不是浏览器直发——从而验证了修复确实生效。若请求仍由浏览器发出,则日志中会出现 CORS 预检(OPTIONS)以及实际请求,且由于浏览器无法解析mock-openai主机名,步骤四根本无法得到模型列表。

源码级原理:服务端如何拉取模型列表

理解了测试流程后,再看源码实现可以更透彻地明白"修复到底做了什么"。

前端:状态层发起 tRPC 调用

前端不再直接发 HTTP 请求,而是通过 tRPC 调用后端。在 app/src/store/aiSettingStore.tsx#L116-L134 中:

fetchProviderModels = new PromiseState({ successMsg: i18n.t('model-list-updated'), function: async (provider: AiProvider) => { // Call backend API to fetch models (enables Docker internal network access) const modelList = await api.ai.fetchProviderModels.mutate({ providerId: provider.id }); await this.aiProviders.call(); return modelList; }, });

调用入口在 ModelDialogContent.tsx#L78-L86,点击"Fetch Models"按钮触发aiSettingStore.fetchProviderModels.call(selectedProvider),随后 tRPC 将providerId传给后端 server/routerTrpc/ai.ts。

服务端:fetchProviderModels 按 Provider 类型分发

server/routerTrpc/ai.ts#L586-L741 中的fetchProviderModels是本次修复的核心。它的流程是:

  1. 按providerId从数据库查询aiProviders记录,查不到则抛出NOT_FOUND;
  2. 通过fetchWithProxy()获取一个已封装 HTTP 代理逻辑的 fetch 函数(见下文);
  3. 根据provider.provider的类型switch分发,构造对应的模型拉取请求:
    • ollama:请求${baseURL}/api/tags,默认http://127.0.0.1:11434,解析data.models中的name字段;
    • openai:请求${baseURL}/models,带Authorization: Bearer <apiKey>头,解析data.data;
    • anthropic:无官方模型列表 API,返回静态清单(claude-3-5-sonnet、claude-3-opus 等 6 个模型);
    • voyageai:同样返回静态清单(voyage-3、voyage-3-lite 等 8 个模型);
    • google:请求${baseURL}/models?key=<apiKey>,解析data.models并去掉models/前缀;
    • azure:请求${baseURL}/openai/models?api-version=2024-02-01,带api-key头;
    • minimax:返回静态清单(MiniMax-M3、MiniMax-M2.7);
    • default(Custom 及其他 OpenAI 兼容服务):请求${baseURL}/models,带 Bearer 头,解析data.data。
  4. 拉取成功后,将模型列表写入aiProviders.config.models持久化到数据库,并返回给前端;前端通过getProviderModels(aiSettingStore.tsx#L136-L145)从provider.config.models读取展示。

正因为请求在服务端容器内发起,http://mock-openai:8080/v1这类内网地址才能被 Docker 内置 DNS 解析,这正是 README 所述修复的本质。

代理封装:fetchWithProxy

server/lib/proxy.ts#L20-L40 中的fetchWithProxy进一步增强了服务端请求的兼容性:若全局配置了 HTTP 代理,它会基于undici的ProxyAgent创建一个带dispatcher的 fetch 包装函数;未配置代理时直接返回原生fetch。因此服务端模型拉取既能走 Docker 内网,也能兼容企业代理等网络环境。

从源码结构看修复的调用链

综合以上代码,本次修复的完整调用链可以概括为:

浏览器点击 Fetch Models → ModelDialogContent.fetchProviderModels(前端组件) → aiSettingStore.fetchProviderModels(PromiseState 状态层) → api.ai.fetchProviderModels.mutate(tRPC 调用) → server/routerTrpc/ai.ts: fetchProviderModels(服务端,按 provider 类型 switch) → fetchWithProxy()(可选 HTTP 代理的 fetch) → GET http://mock-openai:8080/v1/models(Docker 内网解析) → 模型列表写入 aiProviders.config.models → 前端 getProviderModels 渲染模型选项

清理测试环境

测试完成后,按 README 的清理步骤移除容器、网络与数据卷:

docker-compose -f docker-compose.test.yml down -v

其中-v会一并删除postgres_data命名卷,确保下次测试从干净状态开始。

常见问题排查

  • 服务迟迟不进入 healthy 状态:检查docker-compose ps中mock-openai与postgres的健康检查结果,常见原因是端口被占用或镜像未拉取完成;
  • Fetch Models 报错 "Failed to fetch models":优先确认 Base URL 使用了 Docker 服务名(如http://mock-openai:8080/v1)而非localhost,并确认目标容器与 Blinko 容器处于同一blinko-test-network;
  • 模型列表为空:确认 Mock 服务日志中有GET /v1/models记录,若没有记录说明请求未到达服务端,应检查网络与 Base URL 拼接路径(Custom 类型默认请求${baseURL}/models,与 Mock 的/v1/models路径需保持一致)。

小结

通过test-docker这套最小可复现环境,开发者可以在本地一键验证 Blinko 的 AI Provider 模型拉取已从浏览器端迁移到服务端:三容器同处一个 Docker bridge 网络,Mock OpenAI 暴露内网服务名地址,Blinko 服务端通过fetchProviderModels拉取模型列表并落库,日志佐证请求确由容器发出。该方案同样适用于生产环境对接 Ollama 等自建模型服务时的内网连通性验证,是排查"浏览器无法访问 Docker 内网模型服务"类问题的最佳实践参考。

  • 后端
  • 前端
  • 人工智能
  • 大模型
  • RAG
  • 知识库
  • 桌面应用

【免费下载链接】blinko

An open-source, self-hosted personal AI note tool prioritizing privacy, built using TypeScript .

项目地址:https://gitcode.com/gh_mirrors/bl/blinko
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 16:09:07

Java行为验证码源码实战:点击中文文字与滑动图片验证码实现

简介&#xff1a;本资源面向Java后端与全栈开发者&#xff0c;提供一套可直接用于生产环境的用户行为验证码方案&#xff0c;涵盖点击中文文字图片验证码与拖动/滑动图片验证码两种形态&#xff0c;适合需要提升登录、注册等场景防刷能力的中高级开发者参考落地。压缩包共178个…

作者头像 李华
网站建设 2026/10/9 16:08:25

正则表达式入门与实战:从匹配到替换的文本处理核心技巧

开头先聊点实在的。上周帮同事处理一份两万行的业务日志&#xff0c;要找出所有下单超过 3 秒的订单号&#xff0c;连带接口路径和耗时。他原本打算把日志导到 Excel 里手工筛&#xff0c;我一听就摇头&#xff0c;用正则表达式两分钟搞定的事&#xff0c;真不用折腾半小时。类…

作者头像 李华
网站建设 2026/10/9 16:08:15

MySQL 5.7.32在ARM64服务器部署全攻略:从glibc检查到踩坑排查

简介&#xff1a;这是为 ARM 64 位架构&#xff08;AArch64&#xff09;编译的 MySQL 5.7.32 二进制发行包&#xff0c;基于 glibc 2.28&#xff0c;面向树莓派、ARM 服务器等场景下的开发与运维人员&#xff0c;免编译、可离线安装部署&#xff0c;适合缺少现成软件源或需要离…

作者头像 李华
网站建设 2026/10/9 16:06:12

166张图跑通工地扬尘YOLO检测:小数据集实战指南

简介&#xff1a;本资源是面向计算机视觉初学者与工程实践者的建筑工地扬尘目标检测专用YOLO数据集&#xff0c;聚焦于施工场景中尘土颗粒物的识别任务&#xff0c;可直接用于YOLOv5至YOLOv13等主流系列模型的训练与验证&#xff0c;助力智能工地环境监测、AI巡检系统开发等实际…

作者头像 李华
网站建设 2026/10/9 16:06:07

数据库系统工程师能力图谱:从2020真题解构底层核心能力

简介&#xff1a;本资源为2020年全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试——数据库系统工程师科目上午真题及权威答案解析&#xff0c;专为备考软考中级职称的IT从业者、高校相关专业学生及数据库方向初学者设计&#xff0c;助力系统梳理计算机基础…

作者头像 李华
网站建设 2026/10/9 16:04:45

POC测试评分表:功能与接口满足度评估及双签字验收指南

简介&#xff1a;POC测试评分表是一份面向业务人员与技术人员的评估工具文档&#xff0c;用于在性能验证测试&#xff08;Proof of Concept&#xff09;阶段判断系统或解决方案是否满足业务需求与技术指标。表格围绕功能满足程度与接口满足程度两大维度展开&#xff0c;涵盖关键…

作者头像 李华