Configure a Linux ASP.NET Core app for Azure App Service

ASP.NET Core apps must be deployed as compiled binaries. The Visual Studio publishing tool builds the solution and then deploys the compiled binaries directly, whereas the App Service deployment engine deploys the code repository first and then compiles the binaries.

This guide provides key concepts and instructions for ASP.NET Core developers who use a built-in Linux container in App Service. If you've never used Azure App Service, follow the ASP.NET Core quickstart and ASP.NET Core with SQL Database tutorial first.

Show .NET Core version

To show the current .NET Core version, run the following command in the Cloud Shell:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

To show all supported .NET Core versions, run the following command in the Cloud Shell:

az webapp list-runtimes --linux | grep DOTNETCORE

Set .NET Core version

Run the following command in the Cloud Shell to set the .NET Core version to 2.1:

az webapp config set --name <app-name> --resource-group <resource-group-name> --linux-fx-version "DOTNETCORE|2.1"

Customize build automation

If you deploy your app using Git or zip packages with build automation turned on, the App Service build automation steps through the following sequence:

  1. Run custom script if specified by PRE_BUILD_SCRIPT_PATH.
  2. Run dotnet restore to restore NuGet dependencies.
  3. Run dotnet publish to build a binary for production.
  4. Run custom script if specified by POST_BUILD_SCRIPT_PATH.

PRE_BUILD_COMMAND and POST_BUILD_COMMAND are environment variables that are empty by default. To run pre-build commands, define PRE_BUILD_COMMAND. To run post-build commands, define POST_BUILD_COMMAND.

The following example specifies the two variables to a series of commands, separated by commas.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PRE_BUILD_COMMAND="echo foo, scripts/"
az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings POST_BUILD_COMMAND="echo foo, scripts/"

For additional environment variables to customize build automation, see Oryx configuration.

For more information on how App Service runs and builds ASP.NET Core apps in Linux, see Oryx documentation: How .NET Core apps are detected and built.

Access environment variables

In App Service, you can set app settings outside of your app code. Then you can access them in any class using the standard ASP.NET Core dependency injection pattern:

using Microsoft.Extensions.Configuration;

namespace SomeNamespace 
    public class SomeClass
        private IConfiguration _configuration;
        public SomeClass(IConfiguration configuration)
            _configuration = configuration;
        public SomeMethod()
            // retrieve App Service app setting
            var myAppSetting = _configuration["MySetting"];
            // retrieve App Service connection string
            var myConnString = _configuration.GetConnectionString("MyDbConnection");

If you configure an app setting with the same name in App Service and in appsettings.json, for example, the App Service value takes precedence over the appsettings.json value. The local appsettings.json value lets you debug the app locally, but the App Service value lets your run the app in product with production settings. Connection strings work in the same way. This way, you can keep your application secrets outside of your code repository and access the appropriate values without changing your code.

Get detailed exceptions page

When your ASP.NET app generates an exception in the Visual Studio debugger, the browser displays a detailed exception page, but in App Service that page is replaced by a generic HTTP 500 error or An error occurred while processing your request. message. To display the detailed exception page in App Service, Add the ASPNETCORE_ENVIRONMENT app setting to your app by running the following command in the Cloud Shell.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings ASPNETCORE_ENVIRONMENT="Development"

Detect HTTPS session

In App Service, SSL termination happens at the network load balancers, so all HTTPS requests reach your app as unencrypted HTTP requests. If your app logic needs to know if the user requests are encrypted or not, configure the Forwarded Headers Middleware in Startup.cs:

  • Configure the middleware with ForwardedHeadersOptions to forward the X-Forwarded-For and X-Forwarded-Proto headers in Startup.ConfigureServices.
  • Add private IP address ranges to the known networks, so that the middleware can trust the App Service load balancer.
  • Invoke the UseForwardedHeaders method in Startup.Configure before calling other middlewares.

Putting all three elements together, your code looks like the following example:

public void ConfigureServices(IServiceCollection services)

    services.Configure<ForwardedHeadersOptions>(options =>
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:"), 104));
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:"), 112));
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:"), 108));

public void Configure(IApplicationBuilder app, IHostingEnvironment env)



For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.

Deploy multi-project solutions

When you deploy an ASP.NET repository to the deployment engine with a .csproj file in the root directory, the engine deploys the project. When you deploy an ASP.NET repository with a .sln file in the root directory, the engine picks the first Web Site or Web Application Project it finds as the App Service app. It's possible for the engine not to pick the project you want.

To deploy a multi-project solution, you can specify the project to use in App Service in two different ways:

Using .deployment file

Add a .deployment file to the repository root and add the following code:

project = <project-name>/<project-name>.csproj

Using app settings

In the Azure Cloud Shell, add an app setting to your App Service app by running the following CLI command. Replace <app-name>, <resource-group-name>, and <project-name> with the appropriate values.

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PROJECT="<project-name>/<project-name>.csproj"

Access diagnostic logs

You can access the console logs generated from inside the container. First, turn on container logging by running the following command in the Cloud Shell:

az webapp log config --name <app-name> --resource-group myResourceGroup --docker-container-logging filesystem

Once container logging is turned on, run the following command to see the log stream:

az webapp log tail --name <app-name> --resource-group myResourceGroup

If you don't see console logs immediately, check again in 30 seconds.


You can also inspect the log files from the browser at https://<app-name>

To stop log streaming at any time, type Ctrl+C.

Open SSH session in browser

To make open a direct SSH session with your container, your app should be running.

Paste the following URL into your browser and replace <app-name> with your app name:


If you're not yet authenticated, you're required to authenticate with your Azure subscription to connect. Once authenticated, you see an in-browser shell, where you can run commands inside your container.

SSH connection


Any changes you make outside the /home directory are stored in the container itself and don't persist beyond an app restart.

To open a remote SSH session from your local machine, see Open SSH session from remote shell.

robots933456 in logs

You may see the following message in the container logs:

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

You can safely ignore this message. /robots933456.txt is a dummy URL path that App Service uses to check if the container is capable of serving requests. A 404 response simply indicates that the path doesn't exist, but it lets App Service know that the container is healthy and ready to respond to requests.

Next steps