What you should know when deploying .NET 6 application to Linux based App Service?

I recently worked with .NET 6 application and from cost efficiency reasons I decided to deploy application to Linux based App Service. Everything didn't happen without problems so this blog post describes what you should know when deploying .NET 6 application to Linux based App Service in Azure.

Why to use Linux based App Service?

Nowadays Linux based App Service have pretty much same features like Windows but pricing is more attempting. Linux based App Service is 50% cheaper than Windows counterpart. Pricing at 11.11.2021:

Windows based App Service (Premium v3 Service Plan) 


Linux based App Service (Premium v3 Service Plan)


Notes about building Azure Infrastructure with Bicep

App Service Plan creation

I struggled some time with multiple provisioning errors after I noticed this blog post by Azure App Service team. You should determine reserved property to true to use Linux.

Quotation from App Service team blog:

Note that the kind property also shows up in App Service Plans (ASP). At this time, the value of this property for the ASP is meaningless and has no impact on your resource. For example, you can set kind to “Linux” for the ASP, but that won’t make your ASP a Linux ASP; the reserved property is what makes this distinction (if reserved= true, it’s a Linux ASP, otherwise it’s a Windows ASP).

Used Bicep code to create App Service Plan:

resource appServicePlan 'Microsoft.Web/serverfarms@2021-02-01' = {
  name: 'plan-myapplication'
  location: resourceGroup().location
  sku: {
    name: 'S1'
    reserved: true
  kind: ((appServicePlanPlatform == 'Linux') ? 'app,linux' : 'windows')

App Service creation

When you're using Windows based App Service netFrameworkVersion property (Site configs) determines the runtime version like this:


Unfortunately same property don't work with Linux. Instead of netFrameworkVersion you have to use linuxFxVersion property. 

Used Bicep code to create App Service Plan:

resource appService 'Microsoft.Web/sites@2021-02-01' = {
  name: 'app-myapplication'
  location: resourceGroup().location
  identity: {
     type: 'SystemAssigned'
    reserved: true
      alwaysOn: true
      ftpsState: 'Disabled'
      appSettings: appSettings
      linuxFxVersion: 'DOTNETCORE|6.0'
      http20Enabled: true
    httpsOnly: true   

There are a few things what you should know about linuxFxVersion property values. List of available built-in runtime values for web app (Linux) can be retrieved with the following Azure CLI command:

az webapp list-runtimes --linux

Currently (11/2021) command returned the following values:


But value DOTNET|6.0 is not working and after deployment Stack selection is empty.


Instead of DOTNET|6.0 you have to use DOTNETCORE|6.0 to get this working.


Notes about deploying application (YAML)

Set runtime argument value to linux-x64 in publish task like this:

    - task: DotNetCoreCLI@2
      displayName: Create application artifact
        command: publish
        projects:  '**/*.csproj'      
        arguments: '--configuration 'Release' --framework 'net6.0' -r 'linux-x64' --self-contained false --output $(Build.ArtifactStagingDirectory)'
        modifyOutputPath: false
        publishWebProjects: false
        zipAfterPublish: True  

YAML Deploy pipeline

Application is executed in Container so you have to manually set Startup Command to get application running. It took some time to figure this out.


You can use startUpCommand property to configure application start up in application deployment task:

         - task: AzureWebApp@1
            displayName: Deploy application
              appType: 'webAppLinux'
              azureSubscription: 'azure-dev'
              appName: 'app-myapplication'
              package: "$(System.ArtifactsDirectory)/application/*.zip"
              deploymentMethod: 'zipDeploy'
              startUpCommand: 'dotnet MyApplication.dll'

Application settings

When using Linux you have to change app setting key separator from colon (:) which is typically used in Windows platform to double underscore (__). Note! underscore separator should also work in Windows.

    "name": "Idp__Authority",
    "value": "",
    "slotSetting": false
    "name": "KeyVault__Uri",
    "value": "",
    "slotSetting": false