DokumentationAspire ausprobieren
DokumentationAusprobieren

Floci integration

Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.

⭐ Community Toolkit Floci logo

The Aspire Floci hosting integration enables you to model Floci — a family of high-performance local cloud emulators — as container resources in your Aspire application. Floci ships one image per cloud, each API-compatible with its respective provider:

  • floci/floci — AWS, 65+ services including Lambda, S3, DynamoDB, SQS, and SNS
  • floci/floci-az — Azure, including Blob/Queue/Table Storage, Cosmos DB, Functions, Event Hubs, and Service Bus
  • floci/floci-gcp — GCP, including Pub/Sub, Firestore, Datastore, Storage, Secret Manager, and Cloud Functions

Every API is available in both C# and TypeScript AppHosts. The integration supports:

  • Running any combination of the AWS, Azure, and GCP emulators as container resources in the same Aspire application.
  • Automatic environment variable injection for dependent services to connect to the emulated cloud.
  • Customizable port and cloud-specific defaults (region, account ID, project ID).
  • Data persistence with named volumes or bind mounts.
  • Docker-socket access for container-backed services (Lambda, Azure Functions, Cloud Run/Cloud SQL).
  • An optional Floci UI web console, attachable to one or all three clouds at once.
  • Custom Quarkus configuration files for the AWS emulator.
  • HTTPS with Aspire-managed certificates for the AWS and Azure emulators.

To start building an Aspire app that uses Floci, install the 📦 CommunityToolkit.Aspire.Hosting.Floci NuGet package:

Terminal
aspire add communitytoolkit-floci

This updates your aspire.config.json with the Floci hosting integration package:

aspire.config.json
{
"packages": {
"CommunityToolkit.Aspire.Hosting.Floci": "*"
}
}

Each cloud has its own dedicated method — AddFlociAws/addFlociAws, AddFlociAzure/addFlociAzure, and AddFlociGcp/addFlociGcp — and each returns its own resource type. Add whichever clouds your app depends on; they can coexist in the same AppHost.

apphost.mts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const aws = await builder.addFlociAws('floci-aws');
const api = await builder.addProject('api', '../Api/Api.csproj');
await api.withFlociAwsReference(aws).waitFor(aws);
await builder.build().run();

WithReference(aws)/withFlociAwsReference(aws) uses the standard Aspire connection string injection and automatically injects the AWS environment variables listed in Environment variables into the dependent resource.

apphost.mts
const azure = await builder.addFlociAzure('floci-az');
const api = await builder.addProject('api', '../Api/Api.csproj');
await api.withFlociAzureReference(azure).waitFor(azure);
apphost.mts
const gcp = await builder.addFlociGcp('floci-gcp', {
defaultProjectId: 'my-project',
});
const api = await builder.addProject('api', '../Api/Api.csproj');
await api.withFlociGcpReference(gcp).waitFor(gcp);

AWS accepts the following customizable properties:

  • Port: The host port Floci listens on (default: 4566)
  • Default Region: AWS region for the emulator (default: us-east-1)
  • Default Account ID: AWS account ID for the emulator (default: 000000000000)
apphost.mts
const aws = await builder.addFlociAws('floci-aws', {
defaultRegion: 'eu-west-1',
defaultAccountId: '123456789012',
});

GCP accepts the following customizable properties:

  • Port: The host port Floci listens on (default: 4588)
  • Default Project ID: GCP project ID for the emulator (default: floci-local)
apphost.mts
const gcp = await builder.addFlociGcp('floci-gcp', {
defaultProjectId: 'my-project',
});

Azure only accepts a custom port; there’s no region/account/project equivalent to configure.

Enable Lambda, Azure Functions, and container-backed services

Section titled “Enable Lambda, Azure Functions, and 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). WithDockerSocket/withDockerSocket works the same way on all three clouds:

apphost.mts
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:

apphost.mts
const aws = await builder.addFlociAws('floci-aws');
await aws.withDockerSocket({ socketPath: '/run/user/1000/podman/podman.sock' });

By default each emulator stores all state in memory. This information is lost when you restart the application. If you want state to persist across app restarts you can use either a data volume or a data bind mount. They are available on all three clouds.

Data volumes automatically switch Floci from in-memory to persistent mode:

apphost.mts
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');

Alternatively, use a host bind mount for directory-based storage:

apphost.mts
const aws = await builder.addFlociAws('floci-aws');
await aws.withDataBindMount('/path/to/data');

Either approach persists resource state across container restarts and allows local inspection of the stored state.

Once a Floci resource is running and referenced by your service, use the matching cloud SDK as you normally would. WithReference in C# or the cloud-specific withFloci*Reference method in TypeScript injects provider-specific settings into the dependent resource.

AWS and GCP SDKs read their emulator endpoint and region or project settings from the injected environment variables. Azure Storage clients don’t automatically read AZURE_STORAGE_CONNECTION_STRING; construct the client from the injected value:

Program.cs
using Azure.Storage.Blobs;
var builder = WebApplication.CreateBuilder(args);
var azureStorageConnectionString =
builder.Configuration["AZURE_STORAGE_CONNECTION_STRING"]
?? throw new InvalidOperationException(
"AZURE_STORAGE_CONNECTION_STRING is not configured.");
builder.Services.AddSingleton(
new BlobServiceClient(azureStorageConnectionString));

After configuring the provider’s SDK client, interact with Floci as you would with the corresponding cloud service. For example, against the AWS emulator:

Service.cs
using Amazon.S3;
using Amazon.S3.Model;
public class StorageService
{
private readonly IAmazonS3 _s3Client;
public StorageService(IAmazonS3 s3Client)
{
_s3Client = s3Client;
}
public async Task CreateBucketAsync(string bucketName)
{
await _s3Client.PutBucketAsync(new PutBucketRequest
{
BucketName = bucketName
});
}
public async Task UploadObjectAsync(string bucketName, string key, Stream stream)
{
await _s3Client.PutObjectAsync(new PutObjectRequest
{
BucketName = bucketName,
Key = key,
InputStream = stream
});
}
}

Run the Floci UI web console alongside an emulator to browse its hosted resources. WithFlociUI/withFlociUI is available on all three cloud resource types:

apphost.mts
const floci = await builder.addFlociAws('floci');
await floci.withFlociUI();

Customize the container name or pin the host port:

apphost.mts
const floci = await builder.addFlociAws('floci');
await floci.withFlociUI({
containerName: 'my-floci-ui',
configureContainer: async (ui) => {
await ui.withHostPort({ port: 14500 });
},
});

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 in C# or the provider-specific reference method in TypeScript:

apphost.mts
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.withAzureReference(azure);
await ui.withGcpReference(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’s a local development tool only.

Mount a custom application.yml to tune any Floci setting that does not have a dedicated extension method. The file is injected read-only at /deployments/config/application.yml — the standard Quarkus Docker config override location. This is currently only available on the AWS emulator:

apphost.mts
const floci = await builder.addFlociAws('floci');
await floci.withConfigFile('./floci.yml');

Example floci.yml that enables debug logging and disables signature validation:

floci.yml
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 don’t have a dedicated extension method.

The AWS and Azure emulators serve HTTP and HTTPS on the same port. Configure a certificate with Aspire’s certificate APIs and the integration maps the provisioned certificate paths to the matching Floci settings:

apphost.mts
const aws = await builder.addFlociAws('floci-aws');
await aws.withHttpsDeveloperCertificate();
const azure = await builder.addFlociAzure('floci-az');
await azure.withHttpsDeveloperCertificate();
const api = await builder.addProject('api', '../Api/Api.csproj');
await api.withFlociAwsReference(aws);
await api.withFlociAzureReference(azure);

Host-process dependents can validate a trusted development certificate without extra client configuration. For container dependents, use WithDeveloperCertificateTrust(true) in C# or withDeveloperCertificateTrust(true) in TypeScript to install the trust bundle.

Available on all three cloud resource types:

apphost.mts
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. Aspire resolves it for the network used by the dependent resource.

Every endpoint-bearing environment variable injected by the integration carries an Aspire endpoint expression rather than a hard-coded address:

Dependent resourceResolved address
Project or executablelocalhost:{hostPort}
Sibling container{flociResourceName}:{targetPort} on the container network

The scheme is http unless you configure a certificate, in which case AWS and Azure use https on the same port.

When an app resource references Floci using WithReference in C# or a cloud-specific withFloci*Reference method in TypeScript, the integration injects the following environment variables:

VariableValue
ConnectionStrings__{name}Emulator URL resolved for the dependent resource
AWS_ENDPOINT_URLEmulator URL resolved for the dependent resource
AWS_DEFAULT_REGIONRegion passed to AddFlociAws/addFlociAws (default: us-east-1)
AWS_ACCESS_KEY_IDtest
AWS_SECRET_ACCESS_KEYtest
VariableValue
ConnectionStrings__{name}Emulator URL resolved for the dependent resource
AZURE_STORAGE_CONNECTION_STRINGDevelopment storage connection string with Blob, Queue, and Table endpoints resolved for the dependent resource, using the well-known devstoreaccount1 credentials
VariableValue
ConnectionStrings__{name}Emulator URL resolved for the dependent resource
PUBSUB_EMULATOR_HOSTEmulator host and port resolved for the dependent resource
FIRESTORE_EMULATOR_HOSTEmulator host and port resolved for the dependent resource
DATASTORE_EMULATOR_HOSTEmulator host and port resolved for the dependent resource
STORAGE_EMULATOR_HOSTFull emulator URL resolved for the dependent resource
SECRET_MANAGER_EMULATOR_HOSTEmulator host and port resolved for the dependent resource
GOOGLE_CLOUD_PROJECTProject ID passed to AddFlociGcp/addFlociGcp (default: floci-local)
CLOUDSDK_CORE_PROJECTSame project ID, for tools that read the gcloud CLI’s config var instead

You can override any of these settings via standard Aspire environment variable configuration. All Floci-specific settings can also be set via FLOCI_-prefixed environment variables.

Floci is ideal for integration testing cloud-dependent code without requiring real cloud credentials or incurring costs. Since each Floci resource is managed as a standard Aspire resource, you can use it in integration tests the same way you use other Aspire resources.

  • AWS (floci/floci) — 65+ services including S3, DynamoDB, Lambda, EC2, SQS, SNS, Kinesis, RDS, CloudFormation, CloudWatch, IAM, and many more
  • Azure (floci/floci-az) — Blob/Queue/Table Storage, Cosmos DB, Functions, Event Hubs, Service Bus
  • GCP (floci/floci-gcp) — Pub/Sub, Firestore, Datastore, Storage, Secret Manager, Cloud Functions

For a complete list of supported services per cloud, visit the Floci documentation.

  • Ensure Docker is running and has sufficient resources.
  • Check that the specified port isn’t already in use.
  • Verify the Floci container image is available locally or can be pulled from Docker Hub.
  • Verify the Floci container is running: docker ps | grep floci
  • Check that the endpoint URL matches the configured port.
  • Ensure the app resource has the correct WithReference or cloud-specific withFloci*Reference call.
  • Verify the bind mount directory has the correct permissions.
  • Check that the host path exists before starting the container.
  • Use absolute paths for bind mounts to avoid path resolution issues.