Skip to content

Commit

Permalink
Add Docker Compose Service Connection
Browse files Browse the repository at this point in the history
* For ChromaDB, Ollama, Qdrant, Redis, Weaviate
* Add docs
  • Loading branch information
eddumelendez authored and markpollack committed May 27, 2024
1 parent 23e448c commit 9c1b1b8
Show file tree
Hide file tree
Showing 24 changed files with 1,012 additions and 0 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<module>spring-ai-test</module>
<module>spring-ai-spring-boot-autoconfigure</module>
<module>spring-ai-retry</module>
<module>spring-ai-spring-boot-docker-compose</module>
<module>spring-ai-spring-boot-testcontainers</module>
<module>spring-ai-spring-cloud-bindings</module>

Expand Down
1 change: 1 addition & 0 deletions spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,5 @@
* xref:contribution-guidelines.adoc[Contribution Guidelines]
* Appendices
** xref:upgrade-notes.adoc[]
** xref:api/docker-compose.adoc[Docker Compose]
** xref:api/testcontainers.adoc[Testcontainers]
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[[docker-compose]]
= Docker Compose

Spring AI provides Spring Boot auto-configuration for establishing a connection to a model service
or vector store running via Docker Compose. To enable it, add the following dependency
to your project's Maven `pom.xml` file:

[source,xml]
----
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-spring-boot-docker-compose</artifactId>
</dependency>
----

or to your Gradle `build.gradle` build file.

[source,groovy]
----
dependencies {
implementation 'org.springframework.ai:spring-ai-spring-boot-docker-compose'
}
----

TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.

== Service Connections

The following service connection factories are provided in the `spring-ai-spring-boot-docker-compose` module:

[cols="|,|"]
|====
| Connection Details | Matched on
| `ChromaConnectionDetails`
| Containers named `chromadb/chroma`, `ghcr.io/chroma-core/chroma`

| `OllamaConnectionDetails`
| Containers named `ollama/ollama`

| `QdrantConnectionDetails`
| Containers named `qdrant/qdrant`

| `RedisConnectionDetails`
| Containers named `redis/redis-stack-server`

| `WeaviateConnectionDetails`
| Containers named `semitechnologies/weaviate`, `cr.weaviate.io/semitechnologies/weaviate`
|====
145 changes: 145 additions & 0 deletions spring-ai-spring-boot-docker-compose/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>spring-ai-spring-boot-docker-compose</artifactId>
<packaging>jar</packaging>
<name>Spring AI Docker Compose</name>
<description>Spring AI Docker Compose</description>
<url>https://github.com/spring-projects/spring-ai</url>

<scm>
<url>https://github.com/spring-projects/spring-ai</url>
<connection>git://github.com/spring-projects/spring-ai.git</connection>
<developerConnection>git@github.com:spring-projects/spring-ai.git</developerConnection>
</scm>

<dependencies>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-spring-boot-autoconfigure</artifactId>
<version>${project.parent.version}</version>
</dependency>

<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf-java.version}</version>
</dependency>

<!-- production dependencies -->

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<!-- Transformers Embedding Client -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-transformers</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<!-- Milvus Vector Store -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-milvus-store</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<!-- Chroma Vector Store -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-chroma-store</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<!-- Weaviate Vector Store -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-weaviate-store</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<!-- Redis Vector Store-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-redis-store</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<!-- Override Jedis version -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>

<!-- Qdrant Vector Store-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-qdrant-store</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>

<!-- test dependencies -->

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-test</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.docker.compose.service.connection.chroma;

import org.springframework.ai.autoconfigure.vectorstore.chroma.ChromaConnectionDetails;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;

/**
* @author Eddú Meléndez
*/
class ChromaDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<ChromaConnectionDetails> {

private static final String[] CHROMA_IMAGE_NAMES = { "chromadb/chroma", "ghcr.io/chroma-core/chroma" };

private static final int CHROMA_PORT = 8000;

protected ChromaDockerComposeConnectionDetailsFactory() {
super(CHROMA_IMAGE_NAMES);
}

@Override
protected ChromaConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new ChromaDockerComposeConnectionDetails(source.getRunningService());
}

/**
* {@link ChromaConnectionDetails} backed by a {@code Chroma} {@link RunningService}.
*/
static class ChromaDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements ChromaConnectionDetails {

private final String host;

private final int port;

ChromaDockerComposeConnectionDetails(RunningService service) {
super(service);
this.host = service.host();
this.port = service.ports().get(CHROMA_PORT);
}

@Override
public String getHost() {
return this.host;
}

@Override
public int getPort() {
return this.port;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2023 - 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.docker.compose.service.connection.ollama;

import org.springframework.ai.autoconfigure.ollama.OllamaConnectionDetails;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;

/**
* @author Eddú Meléndez
*/
class OllamaDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<OllamaConnectionDetails> {

private static final int OLLAMA_PORT = 11434;

protected OllamaDockerComposeConnectionDetailsFactory() {
super("ollama/ollama");
}

@Override
protected OllamaConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new OllamaDockerComposeConnectionDetails(source.getRunningService());
}

/**
* {@link OllamaConnectionDetails} backed by a {@code Ollama} {@link RunningService}.
*/
static class OllamaDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements OllamaConnectionDetails {

private final String baseUrl;

OllamaDockerComposeConnectionDetails(RunningService service) {
super(service);
this.baseUrl = "http://" + service.host() + ":" + service.ports().get(OLLAMA_PORT);
}

@Override
public String getBaseUrl() {
return this.baseUrl;
}

}

}
Loading

0 comments on commit 9c1b1b8

Please sign in to comment.