Skip to content

Commit 4e8c421

Browse files
kivieweddumelendez
andauthored
Add DockerModelRunnerContainer to core (#10183)
Co-authored-by: Eddú Meléndez Gonzales <eddu.melendez@gmail.com>
1 parent 73e0637 commit 4e8c421

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.testcontainers.containers;
2+
3+
import org.testcontainers.containers.wait.strategy.Wait;
4+
import org.testcontainers.utility.DockerImageName;
5+
6+
/**
7+
* Testcontainers proxy container for the Docker Model Runner service
8+
* provided by Docker Desktop.
9+
* <p>
10+
* Supported images: {@code alpine/socat}
11+
* <p>
12+
* Exposed ports: 80
13+
*/
14+
public class DockerModelRunnerContainer extends SocatContainer {
15+
16+
private static final String MODEL_RUNNER_ENDPOINT = "model-runner.docker.internal";
17+
18+
public DockerModelRunnerContainer(String image) {
19+
this(DockerImageName.parse(image));
20+
}
21+
22+
public DockerModelRunnerContainer(DockerImageName image) {
23+
super(image);
24+
withTarget(80, MODEL_RUNNER_ENDPOINT);
25+
waitingFor(Wait.forHttp("/").forResponsePredicate(res -> res.contains("The service is running")));
26+
}
27+
28+
public String getBaseEndpoint() {
29+
return "http://" + getHost() + ":" + getMappedPort(80);
30+
}
31+
32+
public String getOpenAIEndpoint() {
33+
return getBaseEndpoint() + "/engines";
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.testcontainers.containers;
2+
3+
import io.restassured.RestAssured;
4+
import io.restassured.response.Response;
5+
import org.junit.Test;
6+
7+
import static org.assertj.core.api.Assertions.assertThat;
8+
import static org.assertj.core.api.Assumptions.assumeThat;
9+
10+
public class DockerModelRunnerContainerTest {
11+
12+
@Test
13+
public void pullsModelAndExposesInference() {
14+
assumeThat(System.getenv("CI")).isNull();
15+
16+
String modelName = "ai/smollm2:360M-Q4_K_M";
17+
18+
try (
19+
// container {
20+
DockerModelRunnerContainer dmr = new DockerModelRunnerContainer("alpine/socat:1.7.4.3-r0")
21+
// }
22+
) {
23+
dmr.start();
24+
25+
// pullModel {
26+
RestAssured
27+
.given()
28+
.body(String.format("{\"from\":\"%s\"}", modelName))
29+
.post(dmr.getBaseEndpoint() + "/models/create")
30+
.then()
31+
.statusCode(200);
32+
// }
33+
34+
Response modelResponse = RestAssured.get(dmr.getBaseEndpoint() + "/models").thenReturn();
35+
assertThat(modelResponse.body().jsonPath().getList("tags.flatten()")).contains(modelName);
36+
37+
Response openAiResponse = RestAssured.get(dmr.getOpenAIEndpoint() + "/v1/models").prettyPeek().thenReturn();
38+
assertThat(openAiResponse.body().jsonPath().getList("data.id")).contains(modelName);
39+
}
40+
}
41+
}

docs/modules/docker_model_runner.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Docker Model Runner
2+
3+
This module helps connect to [Docker Model Runner](https://docs.docker.com/desktop/features/model-runner/)
4+
provided by Docker Desktop 4.40.0.
5+
6+
## DockerModelRunner's usage examples
7+
8+
You can start a Docker Model Runner proxy container instance from any Java application by using:
9+
10+
<!--codeinclude-->
11+
[Create a DockerModelRunnerContainer](../../core/src/test/java/org/testcontainers/containers/DockerModelRunnerContainerTest.java) inside_block:container
12+
<!--/codeinclude-->
13+
14+
### Pulling the model
15+
16+
Pulling the model is as simple as:
17+
18+
<!--codeinclude-->
19+
[Pull model](../../core/src/test/java/org/testcontainers/containers/DockerModelRunnerContainerTest.java) inside_block:pullModel
20+
<!--/codeinclude-->
21+
22+
## Adding this module to your project dependencies
23+
24+
*Docker Model Runner support is part of the core Testcontainers library.*
25+
26+
Add the following dependency to your `pom.xml`/`build.gradle` file:
27+
28+
=== "Gradle"
29+
```groovy
30+
testImplementation "org.testcontainers:testcontainers:{{latest_version}}"
31+
```
32+
=== "Maven"
33+
```xml
34+
<dependency>
35+
<groupId>org.testcontainers</groupId>
36+
<artifactId>testcontainers</artifactId>
37+
<version>{{latest_version}}</version>
38+
<scope>test</scope>
39+
</dependency>
40+
```
41+

mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ nav:
8282
- modules/chromadb.md
8383
- modules/consul.md
8484
- modules/docker_compose.md
85+
- modules/docker_model_runner.md
8586
- modules/elasticsearch.md
8687
- modules/gcloud.md
8788
- modules/grafana.md

0 commit comments

Comments
 (0)