
Testcontainers Java 接入 Docker Model Runner本地大模型推理测试指南【免费下载链接】testcontainers-javaTestcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.项目地址: https://gitcode.com/GitHub_Trending/te/testcontainers-java导读本文介绍 Testcontainers Java 中的DockerModelRunnerContainer模块它用于连接 Docker Desktop 4.40.0 起内置的 Docker Model Runner 服务让你在 JUnit 测试中直接调用本地大模型LLM的推理能力。读完本文你将掌握如何从任何 Java 应用启动 Model Runner 代理容器、拉取指定模型、获取 OpenAI 兼容的推理端点并了解其底层基于 socat TCP 代理的实现原理。该模块属于 Testcontainers 核心库无需额外添加独立模块依赖。模块概览什么是 Docker Model Runner 容器Docker Model Runner 是 Docker Desktop 提供的一项内置特性Docker Desktop 4.40.0 起可用它允许开发者在本地运行大语言模型。Testcontainers 通过 DockerModelRunnerContainer 这个代理容器把宿主机上的 Model Runner 服务暴露给被测 Java 应用从而让集成测试能够真实调用本地模型推理。从源码结构看DockerModelRunnerContainer.java该容器类直接继承自SocatContainer其核心设计要点包括固定使用alpine/socat镜像作为 TCP 代理将 Docker Model Runner 服务内部主机名model-runner.docker.internal暴露出来暴露端口固定为80启动时通过等待策略确认 Model Runner 服务已就绪就绪标志是 HTTP 根路径/的响应中包含字符串The service is running。需要注意本模块依赖 Docker Desktop 的 Model Runner 特性使用前提是运行环境为 Docker Desktop 4.40.0 及以上版本。启动一个 Docker Model Runner 容器你可以在任何 Java 应用不限于测试类中通过下面的方式创建并启动 Docker Model Runner 代理容器示例取自 DockerModelRunnerContainerTest.javatry ( DockerModelRunnerContainer dmr new DockerModelRunnerContainer(alpine/socat:1.7.4.3-r0) ) { dmr.start(); // 校验服务状态 Response modelResponse RestAssured.get(dmr.getBaseEndpoint() /status).thenReturn(); assertThat(modelResponse.body().asString()).contains(The service is running); }构造函数既支持字符串镜像名也支持DockerImageName对象见 DockerModelRunnerContainer.java。容器启动后getBaseEndpoint()会返回http://host:映射端口格式的基地址例如http://localhost:32768向该地址的/status端点发起请求即可确认 Model Runner 服务状态。值得说明的是容器内部通过 socat 把本机80端口转发到model-runner.docker.internal主机的 Model Runner 服务上因此所有对宿主 Model Runner 的 HTTP 调用都经由这个映射端口转发测试与被测应用之间无需关心 Docker 内部网络细节。拉取模型要在容器启动后自动拉取指定模型使用withModel(...)方法即可示例取自 DockerModelRunnerContainerTest.javaString modelName ai/smollm2:360M-Q4_K_M; try ( DockerModelRunnerContainer dmr new DockerModelRunnerContainer(alpine/socat:1.7.4.3-r0) .withModel(modelName) ) { dmr.start(); // 通过 /models 端点确认模型已就绪 Response modelResponse RestAssured.get(dmr.getBaseEndpoint() /models).thenReturn(); assertThat(modelResponse.body().jsonPath().getList(tags.flatten())).contains(modelName); // 通过 OpenAI 兼容端点确认模型可用 Response openAiResponse RestAssured.get(dmr.getOpenAIEndpoint() /v1/models).thenReturn(); assertThat(openAiResponse.body().jsonPath().getList(data.id)).contains(modelName); }从源码看withModel(String model)只是记录模型名DockerModelRunnerContainer.java真正的拉取动作发生在容器启动完成的回调containerIsStarted中DockerModelRunnerContainer.java组装拉取地址getBaseEndpoint() /models/create构造 JSON 载荷{from: 模型名}通过HttpURLConnection发起POST请求Content-Type为application/json阻塞读取响应体直到拉取完成并在日志中输出Pulling model: ...与Finished pulling model: ...提示。拉取过程可能耗时较长源码日志明确提示 Please be patient在编写长时间运行的测试时需合理设置超时。获取 OpenAI 兼容的推理端点getOpenAIEndpoint()返回 OpenAI 兼容的 API 基地址格式为http://host:映射端口/engines见 DockerModelRunnerContainer.java。这意味着你可以直接使用任何 OpenAI SDK 客户端把 base URL 指向该端点发起对话、补全等推理请求例如http://localhost:32768/engines/v1/models这一点在集成测试中非常实用被测代码只需把模型服务的 base URL 配置为getOpenAIEndpoint()就能以标准 OpenAI 协议调用本地模型无需改动业务代码。底层原理基于 SocatContainer 的 TCP 代理DockerModelRunnerContainer之所以能够访问 Docker Desktop 内部的 Model Runner 服务关键在于其父类 SocatContainerSocatContainer默认使用alpine/socat:1.7.4.3-r0镜像并以/bin/sh作为入口点withTarget(exposedPort, host)会把本容器的某个端口与目标主机端口建立 TCP 转发关系容器启动配置configure()会将所有转发目标拼接成一条 socat 命令例如socat TCP-LISTEN:80,fork,reuseaddr TCP:model-runner.docker.internal:80。DockerModelRunnerContainer在构造时调用withTarget(PORT, MODEL_RUNNER_ENDPOINT)其中MODEL_RUNNER_ENDPOINT为model-runner.docker.internal端口为 80从而把 Model Runner 服务完整代理到容器暴露端口上。这种设计的好处是即便 Docker Desktop 内部服务不对外发布端口测试容器也能以标准 HTTP 方式访问它。添加依赖Docker Model Runner 支持是 Testcontainers 核心库的一部分无需引入额外模块。在项目的pom.xml或build.gradle中添加核心依赖即可版本号{{latest_version}}为占位符请替换为你实际使用的版本当前仓库的gradle.properties中testcontainers.version2.0.5可作为版本参考 Gradlegroovy testImplementation org.testcontainers:testcontainers:{{latest_version}} Mavenxml dependency groupIdorg.testcontainers/groupId artifactIdtestcontainers/artifactId version{{latest_version}}/version scopetest/scope /dependency测试验证与注意事项仓库中的 DockerModelRunnerContainerTest.java 提供了两个典型测试用例可作为你编写自身测试的参考checkStatus启动容器后请求/status断言响应包含The service is running用于验证代理连通性与服务可用性pullsModelAndExposesInference通过withModel(ai/smollm2:360M-Q4_K_M)拉取模型随后验证/models返回的tags与 OpenAI 端点/engines/v1/models返回的data.id均包含该模型名证明模型已就绪且推理端点可用。使用本模块时需注意以下几点环境前提需要 Docker Desktop 4.40.0 及以上版本且 Model Runner 特性已启用测试用例通过assumeThat(System.getenv(CI)).isNull()跳过 CI 环境说明该模块适合在本地开发环境验证模型行为模型拉取耗时withModel会在容器启动后同步等待模型拉取完成较大的模型可能显著延长测试时间请合理设置测试超时镜像固定目前仅支持alpine/socat系列镜像默认1.7.4.3-r0更换镜像需自行确认兼容性端口映射容器暴露端口固定为 80实际映射端口由 Docker 动态分配始终通过getBaseEndpoint()获取真实地址避免硬编码端口。小结DockerModelRunnerContainer为 Testcontainers Java 用户提供了一条接入 Docker Desktop 内置 Model Runner 的捷径基于 socat 的 TCP 代理打通容器与宿主服务withModel一键拉取模型getOpenAIEndpoint提供 OpenAI 兼容接口让基于本地大模型的集成测试变得简单可复现。相关实现与测试分别位于 DockerModelRunnerContainer.java 与 DockerModelRunnerContainerTest.java读者可直接查阅源码深入研究。【免费下载链接】testcontainers-javaTestcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.项目地址: https://gitcode.com/GitHub_Trending/te/testcontainers-java创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考