dotnet / aspire

Tools, templates, and packages to accelerate building observable, production-ready apps
https://learn.microsoft.com/dotnet/aspire
MIT License
3.87k stars 464 forks source link

Using "Microsoft.VisualStudio.Azure.Containers.Tools.Targets" doesn't work with Aspire #5333

Open mdrakiburrahman opened 2 months ago

mdrakiburrahman commented 2 months ago

Is there an existing issue for this?

Describe the bug

Issue

Visual Studio Containers - AKA where your build from Windows is transferred into a Linux container, doesn't work with Aspire.

You get this:

System.AggregateException: 'One or more errors occurred. (The Aspire orchestration component is not installed at "C:\Program Files\dotnet\packs\Aspire.Hosting.Orchestration.win-x64\8.0.0\tools\dcp.exe". The application cannot be run without it.)'

image

And in the Linux Debug container:

image

I think it's because of how the assembly metadata is used by Aspire to figure out the dcp path.

I have dcp installed in the Linux container:

# ------------------------------------------------------------------------------
# DEBUG CONTAINER: 
# Running against Visual Studio where local build is transferred to container
# ------------------------------------------------------------------------------
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS base

USER root
RUN apt-get update && \
    apt-get install -y \
    wget \
    curl \
    libsecret-1-dev
RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash
RUN dotnet workload install aspire

USER app
WORKDIR /app

image

But the issue is, Aspire is looking at the Windows path, because that's where Visual Studio Containers builds things.


Repro

I couldn't find anyone that has tried this, so I gave it a go.

launchSettings.json

  "profiles": {
    "Docker Container Development": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
      "environmentVariables": {
        "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true",
        "ASPNETCORE_URLS": "http://localhost:17145",
        "ASPNETCORE_ENVIRONMENT": "Development",
        "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:21146"
      },
      "publishAllPorts": true,
      "useSSL": false
    },

My csproj (using Aspire 8.1.0):

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <IsAspireHost>true</IsAspireHost>
    <Nullable>enable</Nullable>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>
  <!-- ==== Debugging right inside a docker container ==== -->
  <PropertyGroup>
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
    <DockerfileContext>..\..\..\..\..</DockerfileContext>
    <DockerfileFile>..\..\..\..\docker\Dockerfile.csharp.dev</DockerfileFile>
    <DockerfileRunArguments>-p 17145:17145</DockerfileRunArguments>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" />
    <PackageReference Include="Aspire.Hosting.AppHost" />
  </ItemGroup>
</Project>

Going through the Aspire code for 8.1.0, it looks like passing args for CLIPath and DashboardPath isn't actually used in DCPOptions:

https://github.com/dotnet/aspire/blob/d304c5f6f15bcd4f34f1841b33870cfab88e6937/src/Aspire.Hosting/Dcp/DcpOptions.cs#L115

image

I tried to add a hack to my CSPROJ, to override the assembly values:

  <ItemGroup>
    <AssemblyAttribute Include="System.Reflection.AssemblyMetadata">
      <_Parameter1>DcpCliPath</_Parameter1>
      <_Parameter2>/usr/share/dotnet/packs/Aspire.Hosting.Orchestration.linux-x64/8.1.0/tools/dcp</_Parameter2>
    </AssemblyAttribute>
    <AssemblyAttribute Include="System.Reflection.AssemblyMetadata">
      <_Parameter1>aspiredashboardpath</_Parameter1>
      <_Parameter2>/usr/share/dotnet/packs/Aspire.Dashboard.Sdk.linux-x64/8.1.0/tools/Aspire.Dashboard.dll</_Parameter2>
    </AssemblyAttribute>
  </ItemGroup>

But that didn't work either.

It looks like this PR:

https://github.com/dotnet/aspire/pull/5082

From @mitchdenny adds the Dashboard Path as an args.

But this isn't available as a Nuget release yet.

Expected Behavior

Visual Studio Containers, an awesome extension for debugging your code in a Docker Container, doesn't work with Aspire.

It'd be great if it did, because Visual Studio Containers solves a very real problem (debugging your code in a close-to-production Linux Container runtime).

Steps To Reproduce

Please try to create a simple project with Visual Studio Containers and try to make it work with the latest Aspire Nuget package. You should hit what I hit.

Exceptions (if any)

2024-08-18 20:52:51 info: Aspire.Hosting.DistributedApplication[0]
2024-08-18 20:52:51       Aspire version: 8.1.0+d304c5f6f15bcd4f34f1841b33870cfab88e6937
2024-08-18 20:52:51 info: Aspire.Hosting.DistributedApplication[0]
2024-08-18 20:52:51       Distributed application starting.
2024-08-18 20:52:51 info: Aspire.Hosting.DistributedApplication[0]
2024-08-18 20:52:51       Application host directory is: C:\Users\mdrrahman\Documents\GitHub\AdsHybrid\src\Microsoft.Universal.Aspire.AppHost\Dataplane.EventProcessing\Dataplane.EventProcessing.AppHost
2024-08-18 20:52:51 warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
2024-08-18 20:52:51       Storing keys in a directory '/home/app/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. For more information go to https://aka.ms/aspnet/dataprotectionwarning
2024-08-18 20:52:51 warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
2024-08-18 20:52:51       No XML encryptor configured. Key {b1ec4679-3680-44a7-9e5b-12aab1d11744} may be persisted to storage in unencrypted form.
2024-08-18 20:52:51 fail: Microsoft.Extensions.Hosting.Internal.Host[11]
2024-08-18 20:52:51       Hosting failed to start
2024-08-18 20:52:51       System.IO.FileNotFoundException: The Aspire orchestration component is not installed at "C:\Program Files\dotnet\packs\Aspire.Hosting.Orchestration.win-x64\8.0.0\tools\dcp.exe". The application cannot be run without it.
2024-08-18 20:52:51       File name: 'C:\Program Files\dotnet\packs\Aspire.Hosting.Orchestration.win-x64\8.0.0\tools\dcp.exe'
2024-08-18 20:52:51          at Aspire.Hosting.Dcp.DcpDependencyCheck.GetDcpInfoAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/Dcp/DcpDependencyCheck.cs:line 50
2024-08-18 20:52:51          at Aspire.Hosting.Dcp.DcpHostService.StartAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/Dcp/DcpHostService.cs:line 67
2024-08-18 20:52:51          at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
2024-08-18 20:52:51          at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)

.NET Version info

This is inside my Docker container:


dotnet workload list

Installed Workload Id      Manifest Version      Installation Source
--------------------------------------------------------------------
aspire                     8.1.0/8.0.100         SDK 8.0.400  

$ dotnet --info
.NET SDK:
 Version:           8.0.401
 Commit:            811edcc344
 Workload version:  8.0.400-manifests.56cd0383
 MSBuild version:   17.11.4+37eb419ad

Runtime Environment:
 OS Name:     debian
 OS Version:  12
 OS Platform: Linux
 RID:         linux-x64
 Base Path:   /usr/share/dotnet/sdk/8.0.401/

.NET workloads installed:
Configured to use loose manifests when installing new manifests.
 [aspire]
   Installation Source: SDK 8.0.400
   Manifest Version:    8.1.0/8.0.100
   Manifest Path:       /usr/share/dotnet/sdk-manifests/8.0.100/microsoft.net.sdk.aspire/8.1.0/WorkloadManifest.json
   Install Type:        FileBased

Host:
  Version:      8.0.8
  Architecture: x64
  Commit:       08338fcaa5

.NET SDKs installed:
  8.0.401 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.8 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

Anything else?

No response

mdrakiburrahman commented 2 months ago

If the maintainers of Aspire are not familiar with Visual Studio Containers, and would like me to create a simple hello-world repro app, please let me know, I can create something and link it here.

Else, if you're familiar, you should be able to repro this in 5 minutes, after adding the Visual Studio Containers project into the Aspire Weather Web App Sample.

Please also feel free to ping me (I'm a Microsoft employee on the SQL Server team - Alias mdrrahman) - I can show a quick repro, if that helps.

joseangelyanez commented 2 months ago

I'm seeing exactly the same problem on Windows. image

davidfowl commented 2 months ago

Don't run the apphost inside of a container, it's unclear how that is beneficial as that is essentially tooling code that orchestrates your application. What are you trying to accomplish here?

joseangelyanez commented 2 months ago

My issue was automatically resolved by upgrading Visual Studio