aspire icon indicating copy to clipboard operation
aspire copied to clipboard

Support running composed projects in Docker

Open DamianEdwards opened this issue 1 year ago • 11 comments

It should be possible to configure a composed project resource to run in Docker. We'll need to consider the integration/composition with VS container tools for Docker and whether we build the project in the host or in the container itself.

DamianEdwards avatar Nov 20 '23 19:11 DamianEdwards

Are you talking about something like this:

var builder = DistributedApplication.CreateBuilder(args);
builder.AddProject<Projects.Foo>("foo").AsContainer();

mitchdenny avatar Jan 01 '24 22:01 mitchdenny

Are you talking about something like this:

var builder = DistributedApplication.CreateBuilder(args);
builder.AddProject<Projects.Foo>("foo").AsContainer();

Something like that would be okay, however I think it would be nicer to just support this through the WithLaunchProfile method. I'm not sure if it's possible to check if the launch profile is a docker/container profile and just do the container logic implicitly when that's the case, but if it isn't maybe using a boolean parameter like isContainer or something.

To be clear I might be missing some complications or other things, that could make the AsContainer fluent api method a better option.

andref15 avatar Jan 01 '24 23:01 andref15

I'm thinking it might even be better to do something like this:

var builder = DistributedApplication.CreateBuilder(args);
builder.AddProjectContainer<Projects.Foo>("foo");

I've been playing around with what the developer experience is for folks building extensions to expire based on .NET apps that run in containers. A scenario that I've been playing with is creating a reusable component that allows you to easily receiver webhook notifications from GitHub and forward them to an Azure Storage queue. The container with the actual application logic would be hosted in Docker Hub, and there would be a NuGet package containing extension methods for wiring it up. This is what the usage would look like in a consuming application.

var builder = DistributedApplication.CreateBuilder(args);
var secret = builder.AddSecretStore("mysecrets").AddSecret("webhooksharedsecret");
var queues = builder.AddAzureStorage("azstorage").AddQueue("azqueues");
var webhookReceiver = builder.AddGitHubWebhookReceiver("webhookreceiver", secret, queues);

For the developer building this extension they want to be able to just have an Aspire host that they can run in their own repo that allows them to spin up their web app. Having an API like AddProjectContainer<T>(...) would allow for this scenario:

public static IResourceBuilder<T> AddGitHubWebhookReceiver(this IDistributedApplicationBuilder builder, string name, IResourceBuilder<SecretResource> secret, IResourceBuilder<AzureQueueStorageResource> queues)
{
  #if DEBUG
    return AddProjectContainer(...);
  #endif

   #if !DEBUG
    return AddContainer(...);
   #endif
}

It allows the return type to always be a container, even though in the home repo for the Aspire extension you can build from project sources and attach debuggers etc. AddProjectContainer(...) might rely on something with launch profiles to make this work as you've suggested though.

mitchdenny avatar Jan 02 '24 01:01 mitchdenny

I was thinking more in the lines of specifying a launch profile that runs the project on a container.

From Visual Studio Container Tools for Docker:

"Container (.NET SDK)": {
  "commandName": "SdkContainer",
  "launchBrowser": true,
  "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
  "environmentVariables": {
    "ASPNETCORE_HTTPS_PORTS": "8081",
    "ASPNETCORE_HTTP_PORTS": "8080"
  },
  "publishAllPorts": true,
  "useSSL": true
}

One can always build and publish the container. But one of the added values of Aspire is the full developer experience that includes debugging.

paulomorgado avatar May 10 '24 19:05 paulomorgado

@danegsta I would defer to you. It needs to work on the command line though

davidfowl avatar May 10 '24 19:05 davidfowl

It needs to work on the command line though

If the Aspire host is specifying a launch profile, what difference would that make?

paulomorgado avatar May 10 '24 19:05 paulomorgado

There's some divergence between how SDK container projects get handled in VS and VSCode (VS uses the SdkContainer launch profile type, while VSCode uses tasks.json/launch.json configuration via the vscode-docker extension). The main challenge will be figuring out when we want to build the actual image for the service project. The only way currently to get a container image from the CLI is running publish; VS does extra steps to run the publish command internally when using that particular launch profile.

danegsta avatar May 10 '24 19:05 danegsta

There's some divergence between how SDK container projects get handled in VS and VSCode (VS uses the SdkContainer launch profile type, while VSCode uses tasks.json/launch.json configuration via the vscode-docker extension). The main challenge will be figuring out when we want to build the actual image for the service project. The only way currently to get a container image from the CLI is running publish; VS does extra steps to run the publish command internally when using that particular launch profile.

As long as I can debug inside the container, I don't mind setting up more detailed instructions in Aspire.

paulomorgado avatar May 10 '24 20:05 paulomorgado

@baronfel it would be ideal if this worked natively with .NET container builds

davidfowl avatar May 10 '24 20:05 davidfowl

Let me make sure I understand the request - Some kind of new launch profile that 'dotnet run' understands so it performs a publish instead of a normal build?

baronfel avatar May 10 '24 20:05 baronfel

So that it runs in a container, yes. The publish part is an implementation detail I think, given that's how you get a container today, but the goal is to simply run the app in a container.

DamianEdwards avatar May 10 '24 20:05 DamianEdwards