1. 引言
Docker Model Runner(在撰写本文时随 Docker Desktop 4.40 for Mac with Apple Silicon 推出)彻底改变了本地 AI 开发模式,通过简化大语言模型(LLMs)的部署和管理来解决常见痛点。它解决了复杂的环境配置、高昂的云端推理成本以及数据隐私问题等难题。
通过提供兼容 OpenAI 的推理接口,Model Runner 可无缝集成 Spring AI 等框架,让开发者轻松构建本地驱动的 AI 应用。本文将演示如何搭建 Docker Model Runner 并创建连接它的 Spring AI 应用,最终实现一个功能完备的本地 AI 应用系统。
2. Docker Model Runner 核心特性
Docker Model Runner 是专为简化容器内 LLM 部署和执行设计的工具,它作为 AI 推理引擎支持多种供应商的模型库。 其核心优势包括:
- 简化模型部署:模型以标准 OCI 制品形式托管在 Docker Hub 的 ai 命名空间,可直接拉取运行
- 广泛模型支持:兼容 Mistral、LLaMA、Phi-4 等主流 LLM,提供灵活的选择空间
- 本地推理能力:完全本地化运行,保障数据隐私并消除云端依赖
- OpenAI 兼容接口:标准化 API 设计,与现有 AI 框架无缝集成
3. 环境准备
3.1. 必要条件
✅ 满足以下要求才能开始:
- **Docker Desktop 4.40+**:需安装在 Apple Silicon 的 Mac 上
- **Java 21+**:Spring AI 开发基础环境
- 兼容模型:如 LLaMA 或 Gemma 3 等 Model Runner 支持的 LLM
⚠️ 注意:目前仅支持 Apple Silicon 平台,Windows/Linux 用户需等待后续版本
3.2. Maven 依赖
在 pom.xml
中添加关键依赖(版本号根据实际情况调整):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.0.0-M6</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-spring-boot-testcontainers</artifactId>
<version>1.0.0-M6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.19.8</version>
<scope>test</scope>
</dependency>
4. 配置 Docker Model Runner
本节介绍两种启用 Model Runner 并拉取模型的方式
4.1. 指定 TCP 端口启用
简单粗暴地启用并暴露端口(如 12434):
docker desktop enable model-runner --tcp 12434
此时 Model Runner 监听 http://localhost:12434/engines
。在 Spring AI 中需配置:
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.base-url=http://localhost:12434/engines
spring.ai.openai.chat.options.model=ai/gemma3
4.2. 结合 Testcontainers 启用
不指定端口启用(默认使用 Docker 内部网络):
docker desktop enable model-runner
通过 Testcontainers 动态配置:
@TestConfiguration(proxyBeanMethods = false)
class TestcontainersConfiguration {
@Bean
DockerModelRunnerContainer socat() {
return new DockerModelRunnerContainer("alpine/socat:1.8.0.1");
}
@Bean
DynamicPropertyRegistrar properties(DockerModelRunnerContainer dmr) {
return (registrar) -> {
registrar.add("spring.ai.openai.base-url", dmr::getOpenAIEndpoint);
registrar.add("spring.ai.openai.api-key", () -> "test-api-key");
registrar.add("spring.ai.openai.chat.options.model", () -> "ai/gemma3");
};
}
}
关键机制:socat
容器作为代理,将流量转发到内部 model-runner.docker.internal
服务,实现测试环境隔离。
4.3. 拉取并验证模型
执行命令拉取 Gemma 3 模型:
docker model pull ai/gemma3
验证本地可用性:
docker model list
确认输出包含 ai/gemma3
即表示成功。
5. Spring AI 集成实现
5.1. 创建控制器
@RestController
class ModelRunnerController {
private final ChatClient chatClient;
public ModelRunnerController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@GetMapping("/chat")
public String chat(@RequestParam("message") String message) {
return this.chatClient.prompt()
.user(message)
.call()
.content();
}
}
5.2. TCP 端口模式测试
核心配置:确保 OpenAI 客户端指向本地 Model Runner 接口。启动应用后测试:
curl "http://localhost:8080/chat?prompt=What%20is%20the%20future%20of%20AI%20development?"
响应将由本地运行的 Gemma 3 模型生成。
5.3. Testcontainers 模式测试
编写集成测试类:
@Import(TestcontainersConfiguration.class)
class ModelRunnerApplicationTest {
// ...
@Test
void givenMessage_whenCallChatController_thenSuccess() {
// given
String userMessage = "Hello, how are you?";
// when
ResponseEntity<String> response = restTemplate.getForEntity(
baseUrl + "/chat?message=" + userMessage, String.class);
// then
assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
assertThat(response.getBody()).isNotEmpty();
}
}
测试流程:通过 @Import
注入配置,Testcontainers 自动创建模拟 AI 服务环境,验证 /chat
接口响应。
6. 总结
Docker Model Runner 为本地运行 LLM 提供了开发友好、隐私安全且成本可控的解决方案,特别适合在 Docker 生态中构建 GenAI 应用的开发者。本文演示了其核心能力及与 Spring AI 的集成方案,完整代码可在 GitHub 获取。
踩坑提示:
- ❌ 避免在生产环境直接使用
test-api-key
- ✅ 开发时优先使用 Testcontainers 保证环境隔离
- ⚠️ 注意模型首次拉取耗时较长(取决于网络和模型大小)