Managing container lifetime in .NET Aspire

Posted: (EET/GMT+2)

 

If you use .NET Aspire for local development, the AppHost can start containers for services such as Redis, SQL Server, PostgreSQL, or storage emulators.

By default, this is very convenient. Start the AppHost, and Aspire starts the containers. Stop debugging, and Aspire can stop the containers again.

For some development workflows, however, you may want the container and its data to stay around between runs.

For example, a simple Redis cache dependency might look like this:

var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");

builder.AddProject<Projects.MyFrontend>("frontend")
       .WithReference(cache)
       .WaitFor(cache);

builder.Build().Run();

This works well when the container can be recreated freely. But if you want the container to stay running between AppHost sessions, use WithLifetime:

var cache = builder.AddRedis("cache")
           .WithLifetime(ContainerLifetime.Persistent);

With ContainerLifetime.Persistent, Aspire can reuse the container across multiple runs instead of always creating a fresh one.

This feature can make local development faster because the container is already running when the application starts.

If the container stores useful local data, also configure a data volume:

var cache = builder.AddRedis("cache")
           .WithLifetime(ContainerLifetime.Persistent)
           .WithDataVolume("myredisdata");

This lets the data volume survive even when the container itself needs to be recreated. This in turn is useful for local databases, queues, caches, and emulators where you want a stable test dataset during a longer development session.

For file-based scenarios, a bind mount can also be useful:

var cache = builder.AddRedis("cache")
           .WithLifetime(ContainerLifetime.Persistent)
           .WithDataBindMount(@"C:\Redis\Data");

Use a bind mount when you want to inspect or edit the files directly from Windows. Keep in mind persistent containers are local development behavior. Do not confuse this with how production containers should be deployed or scaled.

If Aspire creates a new container unexpectedly, check whether something changed in the resource configuration. Container image, ports, environment variables, commands, or volume settings can all affect whether an existing container is reused.

Good candidates for persistent containers:

  • local SQL Server test databases
  • Redis caches used during development
  • message brokers with test messages
  • storage emulators
  • demo environments with prepared data.

Tip: if the local state starts causing confusing behavior, delete the container and volume and let Aspire recreate them.

Persistent containers are a small feature, but they remove a common local development annoyance: losing useful test data every time the AppHost stops.

Hope this helps!