Langfuse Testcontainers
A Testcontainers module providing LangfuseContainer, which runs Langfuse, an LLM engineering platform for tracing, evaluating, and debugging AI applications, together with the containers it needs.
Dependencies
Add the module to your project.
-
Gradle
-
Maven
dependencies {
testImplementation "io.arconia:arconia-testcontainers-langfuse"
}
<dependency>
<groupId>io.arconia</groupId>
<artifactId>arconia-testcontainers-langfuse</artifactId>
<scope>test</scope>
</dependency>
Usage
var langfuse = new LangfuseContainer(DockerImageName.parse("langfuse/langfuse:latest"));
langfuse.start();
Langfuse accepts traces via OTLP with the HTTP/Protobuf protocol, at getOtlpTracesUrl(). Authenticate the requests with the Authorization header returned by getBasicAuthHeader(), built from the API keys of the Langfuse project, and send the x-langfuse-ingestion-version header with the value 4, as Langfuse requires for OpenTelemetry exporters.
|
The Langfuse server closes the plaintext HTTP connections that request an upgrade to HTTP/2, as the JDK HTTP client does by default, including the JDK sender of the OpenTelemetry Java exporters (opentelemetry-java#8982). Send the requests over HTTP/1.1, as the Arconia OpenTelemetry exporters do. |
Langfuse starts with an organization, a project, and a user, so that you can explore the traces right away. The UI is available at getLangfuseUrl(), where you sign in as arconia@example.com (email) and password (password). The traces are in the Arconia project.
Override them and any other Langfuse configuration via environment variables, which apply to both the Langfuse web application and the worker. For example, set the API keys of the project.
var langfuse = new LangfuseContainer(DockerImageName.parse("langfuse/langfuse:latest"))
.withEnv("LANGFUSE_INIT_PROJECT_PUBLIC_KEY", "pk-lf-my-project")
.withEnv("LANGFUSE_INIT_PROJECT_SECRET_KEY", "sk-lf-my-project");
The Langfuse worker, PostgreSQL, ClickHouse, Redis, and Floci as the S3-compatible storage start before Langfuse and stop together with it. Set their images via the dedicated methods.
var langfuse = new LangfuseContainer(DockerImageName.parse("langfuse/langfuse:latest"))
.withWorkerImage("langfuse/langfuse-worker:latest")
.withPostgresImage("postgres:latest")
.withClickHouseImage("clickhouse/clickhouse-server:latest")
.withRedisImage("redis:latest")
.withFlociImage("floci/floci:latest");
Langfuse and the containers it needs join the network set via withNetwork(). Otherwise, the container creates a network for them and removes it when it stops.
| In Spring Boot applications, the Langfuse Dev Service runs this container with no code and sends the traces of the application to it. |