Skip to content

Aspire Integration

Chronicle provides first-class support for Microsoft Aspire, making it straightforward to run Chronicle as part of an Aspire distributed application. The Cratis.Chronicle.Aspire package adds a Chronicle resource to your Aspire AppHost, handling container lifecycle, endpoint wiring, and MongoDB configuration automatically.

Add the Cratis.Chronicle.Aspire package to your AppHost project:

Terminal window
dotnet add package Cratis.Chronicle.Aspire

For local development, call AddCratisChronicle() without arguments. This uses the Chronicle development image (cratis/chronicle:latest-development), which bundles MongoDB, so no external database is required.

using Aspire.Hosting;
public static class HostingAspireDevMode
{
public static void ConfigureAppHost(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
var chronicle = builder.AddCratisChronicle();
builder.AddContainer("api", "my-org/my-api")
.WithReference(chronicle);
builder.Build().Run();
}
}

The development image is ideal for:

  • Getting started quickly without additional infrastructure
  • Running in CI pipelines where a full stack is needed

For production or staging environments, use the configure callback. This switches to the slim image (cratis/chronicle:latest-development-slim) — no embedded MongoDB — and lets you wire up an external database resource.

using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Cratis.Chronicle.Aspire;
public static class HostingAspireMongo
{
public static IResourceBuilder<ChronicleResource> ConfigureAppHost(IDistributedApplicationBuilder builder)
{
var mongo = builder.AddConnectionString("chronicle-mongo");
return builder.AddCratisChronicle("chronicle", c =>
c.WithMongoDB(mongo));
}
}

The WithMongoDB method sets the Cratis__Chronicle__Storage__Type and Cratis__Chronicle__Storage__ConnectionDetails environment variables on the Chronicle container using the connection string from the provided MongoDB resource.

mongo can be any IResourceBuilder<IResourceWithConnectionString>, including:

  • A MongoDB Atlas connection string (builder.AddConnectionString("..."))
  • A Mongo container added directly in the AppHost: builder.AddMongoDB("mongo")
  • Any self-hosted or cloud MongoDB resource
using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Cratis.Chronicle.Aspire;
public static class HostingAspirePostgres
{
public static IResourceBuilder<ChronicleResource> ConfigureAppHost(IDistributedApplicationBuilder builder)
{
var postgres = builder.AddConnectionString("chronicle-postgres");
return builder.AddCratisChronicle("chronicle", c =>
c.WithPostgreSql(postgres));
}
}

postgres can be any IResourceBuilder<IResourceWithConnectionString>, including:

  • A connection string (builder.AddConnectionString("..."))
  • A PostgreSQL container: builder.AddPostgres("postgres").AddDatabase("chronicle")
using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Cratis.Chronicle.Aspire;
public static class HostingAspireSqlServer
{
public static IResourceBuilder<ChronicleResource> ConfigureAppHost(IDistributedApplicationBuilder builder)
{
var sql = builder.AddConnectionString("chronicle-sql");
return builder.AddCratisChronicle("chronicle", c =>
c.WithMsSql(sql));
}
}

sql can be any IResourceBuilder<IResourceWithConnectionString>, including:

  • A connection string (builder.AddConnectionString("..."))
  • A SQL Server container: builder.AddSqlServer("sql").AddDatabase("chronicle")

For SQLite, provide the connection string directly (SQLite is file-based and does not require a network resource):

using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Cratis.Chronicle.Aspire;
public static class HostingAspireSqlite
{
public static IResourceBuilder<ChronicleResource> ConfigureAppHost(IDistributedApplicationBuilder builder) =>
builder.AddCratisChronicle("chronicle", c =>
c.WithSqlite("Data Source=/data/chronicle.db"));
}

Pass the Chronicle resource as a connection string reference to your application projects so they receive the correct endpoint at runtime:

using Aspire.Hosting;
using Aspire.Hosting.ApplicationModel;
using Cratis.Chronicle.Aspire;
public static class HostingAspireConnectingClient
{
public static void ConfigureAppHost(IDistributedApplicationBuilder builder, IResourceBuilder<ChronicleResource> chronicle)
{
// Reference any of your application's projects the same way -
// builder.AddProject<Projects.MyApi>("api") when Projects.MyApi is generated from your solution
builder.AddContainer("api", "my-org/my-api")
.WithReference(chronicle);
}
}

The connection string exposed by ChronicleResource uses the chronicle:// scheme and points to the gRPC port (35000 by default), matching the format expected by ChronicleOptions.FromConnectionString().

Chronicle exposes the following ports:

PortEndpoint NameDescription
35000grpcPrimary Chronicle service — gRPC (HTTP/2) and Workbench/API/OAuth/health (HTTP/1.1)

The grpc endpoint is registered automatically when you call AddCratisChronicle(). ChronicleResource no longer exposes a separate management endpoint — everything is served on the single grpc endpoint.

A typical Aspire AppHost Program.cs for a production setup with MongoDB:

using Aspire.Hosting;
public static class HostingAspireCompleteExample
{
public static void ConfigureAppHost(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
var mongo = builder.AddConnectionString("chronicle-mongo");
var chronicle = builder.AddCratisChronicle("chronicle", c =>
c.WithMongoDB(mongo));
builder.AddContainer("api", "my-org/my-api")
.WithReference(chronicle);
builder.Build().Run();
}
}

For development, simplify further by dropping the MongoDB wiring:

using Aspire.Hosting;
public static class HostingAspireCompleteExampleDev
{
public static void ConfigureAppHost(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
var chronicle = builder.AddCratisChronicle();
builder.AddContainer("api", "my-org/my-api")
.WithReference(chronicle);
builder.Build().Run();
}
}
Image tagDescription
cratis/chronicle:latestProduction image — no embedded MongoDB
cratis/chronicle:latest-developmentDevelopment image — includes embedded MongoDB
cratis/chronicle:latest-development-slimDevelopment slim image — no embedded MongoDB

See Production Hosting for guidance on running Chronicle in production environments.