# .NET Buildpack on App Platform App Platform is a fully managed Platform-as-a-Service (PaaS) that deploys applications from Git repositories or container images. It automatically builds, deploys, and scales components while handling all underlying infrastructure. App Platform supports two ways to build an image for your app: [Cloud Native Buildpacks](https://buildpacks.io/) and [Dockerfiles](https://docs.docker.com/engine/reference/builder/). When you give App Platform access to your code, it defaults to using a Dockerfile if one is present in the root of the directory or specified in the app spec. Otherwise, App Platform checks your code to determine what language or framework it uses. If it supports the language or framework, it chooses an appropriate resource type and uses the proper buildpack to build the app and deploy a container. App Platform uses the [Heroku .NET buildpack](https://github.com/heroku/heroku-buildpack-dotnet) to detect and build .NET applications, including C#, Visual Basic, and F# projects using the .NET and ASP.NET Core frameworks. ## .NET Applications using Buildpacks App Platform looks for any of the following files to detect a .NET application: - Solution files: `*.sln`, `*.slnx` - Project files: `*.csproj`, `*.vbproj`, `*.fsproj` - File-based apps: `*.cs` If App Platform detects one of these files in the root directory of your repository, it will apply the .NET buildpack during deployment to build your application. ## Current Buildpack Version and Supported Runtimes App Platform uses version `42` of the Heroku .NET buildpack. The buildpack supports .NET SDK versions 8.0 and later, including: - Ubuntu-22 - .NET 8.0 (8.0.123, 8.0.417) - .NET 9.0 (9.0.113, 9.0.309) - .NET 10.0 (10.0.102) The buildpack supports C#, Visual Basic, and F# projects using the .NET and ASP.NET Core frameworks. A complete list of supported .NET SDK versions is available in the [SDK inventory file](https://github.com/heroku/buildpacks-dotnet/blob/main/buildpacks/dotnet/inventory.toml). ## Specify a .NET SDK Version ### Default Version Configuration By default, the buildpack installs the latest available and compatible .NET SDK version based on the `TargetFramework` property in each project file. The buildpack supports Target Framework Moniker (TFM) values in the format `net{major_version}.0`, for example, `net8.0`, `net9.0`, and `net10.0`. `MyApp.csproj` ```xml net8.0 ``` If a project file doesn’t specify `TargetFramework`, the buildpack looks for a `Directory.Build.props` file in the project directory or any parent directory and uses the `TargetFramework` property if defined there. If a solution references projects targeting different framework versions, the buildpack prioritizes the most recent version when determining which SDK to install. ### Advanced Version Configuration To specify a different .NET SDK version, add a `global.json` file to the root directory. The buildpack supports configuring both the `version` and `rollForward` policy to control SDK installation. `global.json` ```json { "sdk": { "version": "8.0.106", "rollForward": "disable" } } ``` Use the `rollForward: disable` option only when necessary, and regularly update the `version` to maintain security. For general usage, we recommend setting `rollForward` to `latestFeature`. ## Specify a Solution File By default, the buildpack automatically detects which solution, project, or file-based application to build and publish. However, if your codebase contains multiple solution files in the root directory, you must specify which one to use. You can configure the solution file using either an environment variable or a `project.toml` file. ### Using Environment Variable Set the `SOLUTION_FILE` environment variable with a `BUILD_TIME` scope in your app’s spec: `app.yaml` ```yaml services: - name: web git: repo: "https://github.com/example/repo" branch: master envs: - key: SOLUTION_FILE scope: BUILD_TIME value: "MyApp.sln" ``` ### Using project.toml Alternatively, create a `project.toml` file in the root of your project: `project.toml` ```toml [_] schema-version = "0.2" [com.heroku.buildpacks.dotnet] solution_file = "MyApp.sln" ``` **Note**: If you use both an environment variable and a `project.toml` file, the environment variable takes precedence. The solution file must be a simple filename without any directory components and must have a `.sln` or `.slnx` extension. ## Build Behavior ### Build Configuration By default, the buildpack uses the `Release` configuration when building your application. You can customize the build configuration by setting the `BUILD_CONFIGURATION` environment variable: `app.yaml` ```yaml services: - name: web git: repo: "https://github.com/example/repo" branch: master envs: - key: BUILD_CONFIGURATION scope: BUILD_TIME value: "Debug" ``` You can also configure this in `project.toml`: `project.toml` ```toml [_] schema-version = "0.2" [com.heroku.buildpacks.dotnet.msbuild] configuration = "Debug" ``` ### MSBuild Verbosity Level You can control the verbosity level of MSBuild output by setting the `MSBUILD_VERBOSITY_LEVEL` environment variable. Supported values are: - `quiet` (or `q`) - `minimal` (or `m`) - `normal` (or `n`) - `detailed` (or `d`) - `diagnostic` (or `diag`) `app.yaml` ```yaml services: - name: web git: repo: "https://github.com/example/repo" branch: master envs: - key: MSBUILD_VERBOSITY_LEVEL scope: BUILD_TIME value: "detailed" ``` You can also configure this in `project.toml`: `project.toml` ```toml [_] schema-version = "0.2" [com.heroku.buildpacks.dotnet.msbuild] verbosity = "detailed" ``` ### Build Process The buildpack follows these steps during the build process: 1. Detects the .NET SDK version requirement based on the `TargetFramework` property or `global.json` file 2. Downloads and installs the required .NET SDK 3. Restores .NET tools if a `.config/dotnet-tools.json` manifest file exists 4. Runs `dotnet restore` to restore NuGet packages 5. Runs `dotnet publish` to build and publish the application 6. Detects the web process type from published artifacts ## Process Type Detection The buildpack automatically detects process types from published artifacts: - **Web applications** (ASP.NET Core projects using `Microsoft.NET.Sdk.Web` or `Microsoft.NET.Sdk.Razor`): Registered as `web` process type If a `Procfile` is detected, the buildpack skips process type registration and uses the `web` processes defined in the `Procfile`. ## .NET Tools If your application includes a `.config/dotnet-tools.json` manifest file, the buildpack automatically runs `dotnet tool restore` to install the specified tools during the build process. ## Port Binding Your .NET application must listen on the port specified by the `PORT` environment variable. App Platform automatically sets this variable at runtime. Here’s an example with ASP.NET Core that uses the `PORT` variable: `Program.cs` ```csharp var builder = WebApplication.CreateBuilder(args); // Configure the app to listen on the PORT environment variable var port = Environment.GetEnvironmentVariable("PORT") ?? "5000"; builder.WebHost.UseUrls($"http://*:{port}"); var app = builder.Build(); // Application code goes here app.Run(); ``` Alternatively, you can use the `ASPNETCORE_URLS` environment variable which ASP.NET Core automatically recognizes: `app.yaml` ```yaml services: - name: web git: repo: "https://github.com/example/repo" branch: master envs: - key: ASPNETCORE_URLS scope: RUN_TIME value: "http://*:${PORT}" ```