CommunityToolkit.Aspire.Hosting.Floci 13.6.1

Prefix Reserved
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package CommunityToolkit.Aspire.Hosting.Floci --version 13.6.1
                    
NuGet\Install-Package CommunityToolkit.Aspire.Hosting.Floci -Version 13.6.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CommunityToolkit.Aspire.Hosting.Floci" Version="13.6.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Floci" Version="13.6.1" />
                    
Directory.Packages.props
<PackageReference Include="CommunityToolkit.Aspire.Hosting.Floci" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CommunityToolkit.Aspire.Hosting.Floci --version 13.6.1
                    
#r "nuget: CommunityToolkit.Aspire.Hosting.Floci, 13.6.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CommunityToolkit.Aspire.Hosting.Floci@13.6.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CommunityToolkit.Aspire.Hosting.Floci&version=13.6.1
                    
Install as a Cake Addin
#tool nuget:?package=CommunityToolkit.Aspire.Hosting.Floci&version=13.6.1
                    
Install as a Cake Tool

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 WithReference overload, so WithReference(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

For Cosmos DB, use WithCosmos() / withCosmos() to model the Cosmos API as a child resource, then reference it through Aspire's standard connection-string flow:

var azure = builder.AddFlociAzure("floci-az");
var cosmos = azure.WithCosmos();

builder.AddProject<MyApi>("api")
    .WithReference(azure)    // storage variables (optional)
    .WithReference(cosmos)   // ConnectionStrings__cosmos
    .WaitFor(azure);
const azure = await builder.addFlociAzure('floci-az');
const cosmos = await azure.withCosmos();

await builder.addProject('api', '../MyApi/MyApi.csproj')
    .withFlociAzureReference(azure)
    .withReference(cosmos)
    .waitFor(azure);

App side, this is the standard Aspire flow:

builder.AddAzureCosmosClient("cosmos");
Variable Value
ConnectionStrings__{resourceName} (default cosmos) AccountEndpoint={scheme}://{host}:{port}/{account}-cosmos/;AccountKey=… — the well-known Cosmos DB emulator key. Resource name and account name (default devstoreaccount1) are configurable.

The Cosmos child resource is additive, so combine WithReference(cosmos) with WithReference(azure) when you also want the base endpoint / storage variables. (Talking to the floci Cosmos emulator over HTTP from the .NET SDK still needs the usual client-side settings — Gateway mode, and HTTP/1.1 — which are the app's concern, as with any local Cosmos emulator.)

For Storage (Blob, Queue and Table), use WithStorage() / withStorage() to model the storage APIs as a child resource, then reference it through Aspire's standard connection-string flow:

var azure = builder.AddFlociAzure("floci-az");
var storage = azure.WithStorage();

builder.AddProject<MyApi>("api")
    .WithReference(storage)  // ConnectionStrings__storage
    .WaitFor(storage);
const azure = await builder.addFlociAzure('floci-az');
const storage = await azure.withStorage();

await builder.addProject('api', '../MyApi/MyApi.csproj')
    .withReference(storage)
    .waitFor(storage);

App side, this is the standard Aspire flow:

builder.AddAzureBlobServiceClient("storage");
Variable Value
ConnectionStrings__{resourceName} (default storage) DefaultEndpointsProtocol={scheme};AccountName=devstoreaccount1;AccountKey=…;BlobEndpoint={scheme}://{ip}:{port}/devstoreaccount1;QueueEndpoint=…;TableEndpoint=…;

The endpoints use the emulator's IPv4 address (127.0.0.1 for host processes) instead of localhost, because the Azure Storage SDKs only read the account name from the URL path when the host is an IP address. The storage resource has no health check of its own: it reports the Floci Azure container's health, so WaitFor(storage) waits until the emulator is ready.

In an AppHost that also publishes, add Aspire's AddAzureStorage resource in the publish branch and reference the Floci storage child in the run branch. Pointing an AzureStorageResource at Floci with a connection-string redirect instead leaves Aspire's Azure Storage health checks waiting for a connection string that is never provisioned, so those resources stay Unhealthy.

For Service Bus, use WithServiceBus() / withServiceBus() to model the AMQP data plane as a child resource, then reference it with WithReference() / withFlociAzureServiceBusReference():

var azure = builder.AddFlociAzure("floci-az")
    .WithDockerSocket();
var serviceBus = azure.WithServiceBus();

builder.AddProject<MyApi>("api")
    .WithReference(serviceBus) // ConnectionStrings__servicebus
    .WaitFor(azure);
const azure = (await builder.addFlociAzure('floci-az')).withDockerSocket();
const serviceBus = await azure.withServiceBus();

await builder.addProject('api', '../MyApi/MyApi.csproj')
    .withFlociAzureServiceBusReference(serviceBus)
    .waitFor(azure);

App side, this is the standard Aspire flow:

builder.AddAzureServiceBusClient("servicebus");
Variable Value
ConnectionStrings__{resourceName} (default servicebus) Endpoint=sb://{host}:{amqpPort};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true; — {host} is localhost for host processes and the container runtime's host gateway for containers

WithServiceBus sets FLOCI_AZ_SERVICES_SERVICE_BUS_MOCKED=false and FLOCI_AZ_SERVICES_SERVICE_BUS_START_ON_BOOT=true. The integration selects free AMQP and AMQPS host ports at startup, allocates the child's proxyless endpoints, and passes those same ports to Floci; pass amqpPort / amqpTlsPort to use fixed ports. The management plane (for example, ServiceBusAdministrationClient) remains on the base endpoint from WithReference(azure). Requires WithDockerSocket() and floci-az 0.12.0 or later.

AMQP and AMQPS must use different host ports. Repeated calls on the same emulator return the existing child only when the resource name and any specified ports match.

For container consumers, the Service Bus reference helper adds floci-servicebus-host.internal:host-gateway to the container's host mappings and uses the sidecar's published AMQP port. This requires a container runtime supporting Docker's --add-host=...:host-gateway option. Use the Service Bus reference helper instead of passing the child's raw endpoint or connection string expression to a container.

Service Bus support is run-only. WithServiceBus() throws in publish mode because the Artemis sidecar has no deployable backing resource in the Aspire model. In an AppHost that also publishes, call it inside if (builder.ExecutionContext.IsRunMode) and reference a deployable Service Bus resource in the publish branch.

When running multiple Floci Azure emulators on the same Docker host, set a different FLOCI_AZ_DOCKER_RESOURCE_NAMESPACE environment variable on each emulator to keep their sidecar container names separate. Also pass a globally unique child name to each additional WithServiceBus call, for example secondAzure.WithServiceBus("second-servicebus"). The first can keep the default servicebus connection name; references to the second inject ConnectionStrings__second-servicebus. Port allocation alone does not isolate resource or sidecar names.

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/withFlociUI runs 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 WithReference overloads 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 localhost only) 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.6.2-beta.959 45 10/27/2026
13.6.1 769 10/26/2026
13.6.1-beta.950 51 10/26/2026
13.6.1-beta.938 55 10/24/2026
13.6.1-beta.935 77 10/15/2026
13.6.1-beta.933 62 10/13/2026
13.6.1-beta.930 59 10/11/2026
13.6.0 7,937 10/1/2026
13.6.0-beta.914 58 10/1/2026
13.6.0-beta.910 61 9/30/2026
13.5.1-beta.895 145 9/29/2026
13.5.1-beta.806 68 9/28/2026
13.5.1-beta.803 58 9/28/2026
13.5.1-beta.781 63 9/28/2026
13.5.1-beta.779 63 9/28/2026
13.5.1-beta.777 56 9/28/2026
13.5.1-beta.776 63 9/28/2026
13.5.1-beta.775 63 9/27/2026
13.5.1-beta.770 62 9/25/2026
13.5.1-beta.767 68 9/22/2026
Loading failed