CommunityToolkit.Aspire.Hosting.Floci
13.5.0
Prefix Reserved
See the version list below for details.
dotnet add package CommunityToolkit.Aspire.Hosting.Floci --version 13.5.0
NuGet\Install-Package CommunityToolkit.Aspire.Hosting.Floci -Version 13.5.0
<PackageReference Include="CommunityToolkit.Aspire.Hosting.Floci" Version="13.5.0" />
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Floci" Version="13.5.0" />
<PackageReference Include="CommunityToolkit.Aspire.Hosting.Floci" />
paket add CommunityToolkit.Aspire.Hosting.Floci --version 13.5.0
#r "nuget: CommunityToolkit.Aspire.Hosting.Floci, 13.5.0"
#:package CommunityToolkit.Aspire.Hosting.Floci@13.5.0
#addin nuget:?package=CommunityToolkit.Aspire.Hosting.Floci&version=13.5.0
#tool nuget:?package=CommunityToolkit.Aspire.Hosting.Floci&version=13.5.0
CommunityToolkit.Aspire.Hosting.Floci
Overview
This Aspire integration runs Floci in a container. Floci is a family of high-performance local cloud emulators — floci/floci (AWS, 65+ services including Lambda, S3, DynamoDB, SQS, SNS), floci/floci-az (Azure — Blob/Queue/Table Storage, Cosmos DB, Functions, Event Hubs, Service Bus), and floci/floci-gcp (GCP — Pub/Sub, Firestore, Datastore, Storage, Secret Manager, Cloud Functions) — each API-compatible with its respective cloud.
Every example below is shown in both C# and TypeScript (polyglot AppHost) form.
Usage
Example 1: Add an emulator with default configuration
AWS
var builder = DistributedApplication.CreateBuilder(args);
var aws = builder.AddFlociAws("floci-aws");
var api = builder.AddProject<MyApi>("api")
.WithReference(aws)
.WaitFor(aws);
builder.Build().Run();
const builder = await createBuilder();
const aws = await builder.addFlociAws('floci-aws');
const api = await builder.addProject('api', '../MyApi/MyApi.csproj')
.withFlociAwsReference(aws)
.waitFor(aws);
await builder.build().run();
WithReference(aws) / withFlociAwsReference(aws) uses the standard Aspire connection string injection and additionally injects the environment variables the AWS SDKs already read, so no SDK configuration is needed in the dependent:
| Variable | Value |
|---|---|
ConnectionStrings__floci-aws |
http://localhost:{port} (standard Aspire connection string) |
AWS_ENDPOINT_URL |
The emulator endpoint, resolved by Aspire per dependent (see Endpoint resolution) |
AWS_DEFAULT_REGION |
Region passed to AddFlociAws/addFlociAws (default: us-east-1) |
AWS_ACCESS_KEY_ID |
test |
AWS_SECRET_ACCESS_KEY |
test |
Note: In C# each cloud contributes a
WithReferenceoverload, soWithReference(aws)is picked by argument type. The generated TypeScript bindings have no overload resolution, so each cloud gets its own method:withFlociAwsReference,withFlociAzureReference,withFlociGcpReference.
Azure
var azure = builder.AddFlociAzure("floci-az");
builder.AddProject<MyApi>("api")
.WithReference(azure)
.WaitFor(azure);
const azure = await builder.addFlociAzure('floci-az');
await builder.addProject('api', '../MyApi/MyApi.csproj')
.withFlociAzureReference(azure)
.waitFor(azure);
WithReference(azure) / withFlociAzureReference(azure) injects the following environment variables into the dependent resource:
| Variable | Value |
|---|---|
ConnectionStrings__floci-az |
http://localhost:{port} (standard Aspire connection string) |
AZURE_STORAGE_CONNECTION_STRING |
Development storage connection string pointed at the Floci Azure endpoint, carrying BlobEndpoint, QueueEndpoint and TableEndpoint and the well-known devstoreaccount1 dev credentials |
GCP
var gcp = builder.AddFlociGcp("floci-gcp", defaultProjectId: "my-project");
builder.AddProject<MyApi>("api")
.WithReference(gcp)
.WaitFor(gcp);
const gcp = await builder.addFlociGcp('floci-gcp', {
defaultProjectId: 'my-project',
});
await builder.addProject('api', '../MyApi/MyApi.csproj')
.withFlociGcpReference(gcp)
.waitFor(gcp);
WithReference(gcp) / withFlociGcpReference(gcp) injects the following environment variables into the dependent resource:
| Variable | Value |
|---|---|
ConnectionStrings__floci-gcp |
http://localhost:{port} (standard Aspire connection string) |
PUBSUB_EMULATOR_HOST |
{host}:{port} (see Endpoint resolution) |
FIRESTORE_EMULATOR_HOST |
{host}:{port} |
DATASTORE_EMULATOR_HOST |
{host}:{port} |
STORAGE_EMULATOR_HOST |
http://{host}:{port} — the Storage SDK expects a full URL here, unlike the others |
SECRET_MANAGER_EMULATOR_HOST |
{host}:{port} |
GOOGLE_CLOUD_PROJECT |
Project ID passed to AddFlociGcp/addFlociGcp (default: floci-local) |
CLOUDSDK_CORE_PROJECT |
Same project ID, for tools that read the gcloud CLI's config var instead |
Example 2: Enable Lambda / Azure Functions / container-backed services
Each emulator needs access to the Docker socket to launch sibling containers for its container-backed services (AWS Lambda, Azure Functions, GCP Cloud Run/Cloud SQL):
var aws = builder.AddFlociAws("floci-aws")
.WithDockerSocket();
var azure = builder.AddFlociAzure("floci-az")
.WithDockerSocket();
var gcp = builder.AddFlociGcp("floci-gcp")
.WithDockerSocket();
const aws = await builder.addFlociAws('floci-aws');
await aws.withDockerSocket();
const azure = await builder.addFlociAzure('floci-az');
await azure.withDockerSocket();
const gcp = await builder.addFlociGcp('floci-gcp');
await gcp.withDockerSocket();
On non-standard Docker installations (e.g. Podman, Rancher Desktop), pass the socket path explicitly — this works the same way on all three clouds:
var aws = builder.AddFlociAws("floci-aws")
.WithDockerSocket("/run/user/1000/podman/podman.sock");
const aws = await builder.addFlociAws('floci-aws');
await aws.withDockerSocket({ socketPath: '/run/user/1000/podman/podman.sock' });
Example 3: Persistent storage
By default each emulator stores all state in memory. Use WithDataVolume/withDataVolume to persist state across restarts — available on all three clouds:
var aws = builder.AddFlociAws("floci-aws")
.WithDataVolume("floci-data");
var azure = builder.AddFlociAzure("floci-az")
.WithDataVolume("floci-az-data");
var gcp = builder.AddFlociGcp("floci-gcp")
.WithDataVolume("floci-gcp-data");
const aws = await builder.addFlociAws('floci-aws');
await aws.withDataVolume('floci-data');
const azure = await builder.addFlociAzure('floci-az');
await azure.withDataVolume('floci-az-data');
const gcp = await builder.addFlociGcp('floci-gcp');
await gcp.withDataVolume('floci-gcp-data');
Or use a host bind mount:
var aws = builder.AddFlociAws("floci-aws")
.WithDataBindMount("/path/to/data");
const aws = await builder.addFlociAws('floci-aws');
await aws.withDataBindMount('/path/to/data');
Example 4: Custom region/account/project
var aws = builder.AddFlociAws("floci-aws",
defaultRegion: "eu-west-1",
defaultAccountId: "123456789012");
var gcp = builder.AddFlociGcp("floci-gcp",
defaultProjectId: "my-project");
const aws = await builder.addFlociAws('floci-aws', {
defaultRegion: 'eu-west-1',
defaultAccountId: '123456789012',
});
const gcp = await builder.addFlociGcp('floci-gcp', {
defaultProjectId: 'my-project',
});
Example 5: Floci UI web console — single cloud
Run the Floci UI web console alongside an emulator to browse its hosted resources:
var floci = builder.AddFlociAws("floci")
.WithFlociUI();
const floci = await builder.addFlociAws('floci');
await floci.withFlociUI();
Customize the container name or pin the host port:
var floci = builder.AddFlociAws("floci")
.WithFlociUI(ui => ui.WithHostPort(14500), containerName: "my-floci-ui");
const floci = await builder.addFlociAws('floci');
await floci.withFlociUI({
containerName: 'my-floci-ui',
configureContainer: async (ui) => {
await ui.withHostPort({ port: 14500 });
},
});
Note: Floci also has a built-in mechanism to launch the UI as a sidecar container on demand, but that relies on Floci itself talking to the Docker socket and self-discovered endpoints, which does not play well with Aspire's DCP-managed container networking.
WithFlociUI/withFlociUIruns the UI as a first-class Aspire resource instead.
Example 6: Floci UI web console — all three clouds in one console
A single UI console can attach to any combination of clouds — call WithFlociUI/withFlociUI on whichever cloud creates the console, then attach the others with WithReference/withCloudReference*:
var aws = builder.AddFlociAws("floci-aws");
var azure = builder.AddFlociAzure("floci-az");
var gcp = builder.AddFlociGcp("floci-gcp");
aws.WithFlociUI(configureContainer: ui =>
{
ui.WithReference(azure);
ui.WithReference(gcp);
});
const aws = await builder.addFlociAws('floci-aws');
const azure = await builder.addFlociAzure('floci-az');
const gcp = await builder.addFlociGcp('floci-gcp');
await aws.withFlociUI({
configureContainer: async (ui) => {
await ui.withFlociAzureReference(azure);
await ui.withFlociGcpReference(gcp);
},
});
The UI container (floci/floci-ui) is added as a child resource of whichever cloud resource created it, wired to each attached cloud's endpoint over the container network (FLOCI_ENDPOINT/FLOCI_AZURE_ENDPOINT/FLOCI_GCP_ENDPOINT), and is excluded from the deployment manifest (it is a local development tool only).
Note: In C# these are
WithReferenceoverloads on the UI resource builder — the compiler picks the right one from the argument type. In TypeScript there is no overload resolution on the generated bindings, so each cloud gets its own method:withFlociAwsReference,withFlociAzureReference,withFlociGcpReference.
Example 7: Custom Quarkus configuration file (AWS only)
Mount a hand-crafted application.yml to tune any Floci setting that does not have an extension method. The file is injected read-only at /deployments/config/application.yml — the standard Quarkus Docker config override location.
var floci = builder.AddFlociAws("floci")
.WithConfigFile("./floci.yml");
const floci = await builder.addFlociAws('floci');
await floci.withConfigFile('./floci.yml');
A minimal floci.yml that enables debug logging and disables signature validation:
floci:
auth:
validate-signatures: false
quarkus:
log:
level: DEBUG
All Floci settings can also be set via FLOCI_-prefixed environment variables — WithConfigFile/withConfigFile is only needed for settings that do not have a dedicated extension method. This is currently only available for the AWS emulator.
Example 8: TLS / HTTPS (AWS and Azure)
Both images serve HTTP and HTTPS on the same port, so enabling TLS never changes the port — only the scheme handed to dependents.
The integration hooks Aspire's own certificate plumbing, so the idiomatic Aspire APIs just work: configure a certificate and the emulator picks it up. Nothing Floci-specific to call.
var aws = builder.AddFlociAws("floci-aws")
.WithHttpsDeveloperCertificate(); // Aspire API — provisions and mounts the key pair
var azure = builder.AddFlociAzure("floci-az")
.WithHttpsDeveloperCertificate();
builder.AddProject<MyApi>("api")
.WithReference(aws) // AWS_ENDPOINT_URL = https://...
.WithReference(azure); // AZURE_STORAGE_CONNECTION_STRING = DefaultEndpointsProtocol=https;...
const aws = await builder.addFlociAws('floci-aws');
await aws.withHttpsDeveloperCertificate();
Under the hood the integration registers a WithHttpsCertificateConfiguration callback that maps Aspire's provisioned paths onto the image's own settings, and switches the primary endpoint to https before start:
| Aspire-provided value | AWS | Azure |
|---|---|---|
| — | FLOCI_TLS_ENABLED=true |
FLOCI_AZ_TLS_ENABLED=true |
| — | FLOCI_TLS_SELF_SIGNED=false |
FLOCI_AZ_TLS_SELF_SIGNED=false |
context.CertificatePath |
FLOCI_TLS_CERT_PATH |
FLOCI_AZ_TLS_CERT_PATH |
context.KeyPath |
FLOCI_TLS_KEY_PATH |
FLOCI_AZ_TLS_KEY_PATH |
Because the ASP.NET Core development certificate is already in your machine's trust store, host-process dependents validate it with no extra client configuration. For container dependents, add Aspire's WithDeveloperCertificateTrust(true) to install the trust bundle. Any other Aspire certificate source (WithHttpsCertificate(...), WithCertificatesFromFile, WithCertificatesFromStore) is honoured the same way.
Reach for this when a client refuses plain HTTP — the Cosmos DB Java SDK, or the azurerm Terraform/OpenTofu provider, which discovers the cloud over https://<host>/metadata/endpoints.
Plain HTTP stays the default. Unlike HTTPS-first resources, merely having a trusted development certificate on the machine does not flip an existing AppHost to
https— a certificate has to be asked for explicitly.The Floci UI console keeps using the emulator's plain-HTTP listener even when TLS is on. It reaches the emulator by container-network name, which neither the development certificate (SAN
localhostonly) nor a host-issued certificate covers, so HTTPS there would fail hostname validation regardless of trust. Since both protocols share the port, the console connects normally.The GCP emulator (
floci/floci-gcp) has no HTTPS listener, so no certificate callback is registered for it and a configured certificate has no effect there.
Connection string / endpoint properties
Available on all three cloud resource types:
var endpoint = floci.PrimaryEndpoint;
var host = floci.Host;
var port = floci.Port;
var connectionString = floci.ConnectionStringExpression;
const endpoint = await floci.primaryEndpoint();
const host = await floci.host();
const port = await floci.port();
const connectionString = await floci.connectionStringExpression();
connectionStringExpression is an unresolved endpoint expression — see below.
Endpoint resolution
Every environment variable this integration injects carries an Aspire endpoint expression rather than a literal address, so Aspire resolves it against the network the dependent is on:
| Dependent | Resolves to |
|---|---|
| Project / executable (host process) | localhost:{hostPort} |
| Sibling container | {flociResourceName}:{targetPort} on the container network |
Nothing is hard-coded to host.docker.internal, so this works on Docker Desktop, plain Linux Docker, Podman and Rancher Desktop alike.
The scheme is http unless a certificate has been configured, in which case it becomes https on the same port.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Aspire.Hosting (>= 13.5.0)
- MessagePack (>= 2.5.302)
-
net8.0
- Aspire.Hosting (>= 13.5.0)
- MessagePack (>= 2.5.302)
-
net9.0
- Aspire.Hosting (>= 13.5.0)
- MessagePack (>= 2.5.302)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 13.5.1-beta.736 | 36 | 9/1/2026 |
| 13.5.0 | 310 | 8/25/2026 |
| 13.5.0-beta.731 | 61 | 8/24/2026 |