Use multiple environments in ASP.NET Core

By Rick Anderson

ASP.NET Core provides support for setting application behavior at runtime with environment variables.

View or download sample code (how to download)

Environments

ASP.NET Core reads the environment variable ASPNETCORE_ENVIRONMENT at application startup and stores that value in IHostingEnvironment.EnvironmentName. ASPNETCORE_ENVIRONMENT can be set to any value, but three values are supported by the framework: Development, Staging, and Production. If ASPNETCORE_ENVIRONMENT isn't set, it will default to Production.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }

    if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
}

The preceding code:

The Environment Tag Helper uses the value of IHostingEnvironment.EnvironmentName to include or exclude markup in the element:

@page
@inject Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnv
@model AboutModel
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@Model.Message</h3>

<p> ASPNETCORE_ENVIRONMENT = @hostingEnv.EnvironmentName</p>

<environment include="Development">
    <div>&lt;environment include="Development"&gt;</div>
</environment>
<environment exclude="Development">
    <div>&lt;environment exclude="Development"&gt;</div>
</environment>
<environment include="Staging,Development,Staging_2">
    <div>
        &lt;environment include="Staging,Development,Staging_2"&gt;
    </div>
</environment>

Note: On Windows and macOS, environment variables and values are not case sensitive. Linux environment variables and values are case sensitive by default.

Development

The development environment can enable features that shouldn't be exposed in production. For example, the ASP.NET Core templates enable the developer exception page in the development environment.

The environment for local machine development can be set in the Properties\launchSettings.json file of the project. Environment values set in launchSettings.json override values set in the system environment.

The following JSON shows three profiles from a launchSettings.json file:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:54339/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "WebApp1": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Staging"
      },
      "applicationUrl": "http://localhost:54340/"
    },
    "Kestrel Staging": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_My_Environment": "1",
        "ASPNETCORE_DETAILEDERRORS": "1",
        "ASPNETCORE_ENVIRONMENT": "Staging"
      },
      "applicationUrl": "http://localhost:51997/"
    }
  }
}

Note

The applicationUrl property in launchSettings.json can specify a list of server URLs. Use a semicolon between the URLs in the list:

"WebApplication1": {
   "commandName": "Project",
   "launchBrowser": true,
   "applicationUrl": "https://localhost:5001;http://localhost:5000",
   "environmentVariables": {
     "ASPNETCORE_ENVIRONMENT": "Development"
   }
}

When the application is launched with dotnet run, the first profile with "commandName": "Project" will be used. The value of commandName specifies the web server to launch. commandName can be one of :

  • IIS Express
  • IIS
  • Project (which launches Kestrel)

When an app is launched with dotnet run:

  • launchSettings.json is read if available. environmentVariables settings in launchSettings.json override environment variables.
  • The hosting environment is displayed.

The following output shows an app started with dotnet run:

PS C:\Webs\WebApp1> dotnet run
Using launch settings from C:\Webs\WebApp1\Properties\launchSettings.json...
Hosting environment: Staging
Content root path: C:\Webs\WebApp1
Now listening on: http://localhost:54340
Application started. Press Ctrl+C to shut down.

The Visual Studio Debug tab provides a GUI to edit the launchSettings.json file:

Project Properties Setting Environment variables

Changes made to project profiles may not take effect until the web server is restarted. Kestrel must be restarted before it will detect changes made to its environment.

Warning

launchSettings.json shouldn't store secrets. The Secret Manager tool can be used to store secrets for local development.

Production

The production environment should be configured to maximize security, performance, and application robustness. Some common settings that differ from development include:

  • Caching.
  • Client-side resources are bundled, minified, and potentially served from a CDN.
  • Diagnostic error pages disabled.
  • Friendly error pages enabled.
  • Production logging and monitoring enabled. For example, Application Insights.

Setting the environment

It's often useful to set a specific environment for testing. If the environment isn't set, it will default to Production which disables most debugging features.

The method for setting the environment depends on the operating system.

Azure

For Azure app service:

  • Select the Application settings blade.
  • Add the key and value in App settings.

Windows

To set the ASPNETCORE_ENVIRONMENT for the current session, if the app is started using dotnet run, the following commands are used

Command line

set ASPNETCORE_ENVIRONMENT=Development

PowerShell

$Env:ASPNETCORE_ENVIRONMENT = "Development"

These commands take effect only for the current window. When the window is closed, the ASPNETCORE_ENVIRONMENT setting reverts to the default setting or machine value. In order to set the value globally on Windows open the Control Panel > System > Advanced system settings and add or edit the ASPNETCORE_ENVIRONMENT value.

System Advanced Properties

ASPNET Core Environment Variable

web.config

See the Setting environment variables section of the ASP.NET Core Module configuration reference topic.

Per IIS Application Pool

To set environment variables for individual apps running in isolated Application Pools (supported on IIS 10.0+), see the AppCmd.exe command section of the Environment Variables <environmentVariables> topic.

macOS

Setting the current environment for macOS can be done in-line when running the application;

ASPNETCORE_ENVIRONMENT=Development dotnet run

or using export to set it prior to running the app.

export ASPNETCORE_ENVIRONMENT=Development

Machine level environment variables are set in the .bashrc or .bash_profile file. Edit the file using any text editor and add the following statment.

export ASPNETCORE_ENVIRONMENT=Development

Linux

For Linux distros, use the export command at the command line for session based variable settings and bash_profile file for machine level environment settings.

Configuration by environment

See Configuration by environment for more information.

Environment based Startup class and methods

When an ASP.NET Core app starts, the Startup class bootstraps the app. If a class Startup{EnvironmentName} exists, that class will be called for that EnvironmentName:

public class StartupDevelopment
{
    public StartupDevelopment(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }

        if (env.IsProduction() || env.IsStaging())
        {
            throw new Exception("Not development.");
        }

        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();
    }
}

Note: Calling WebHostBuilder.UseStartup overrides configuration sections.

Configure and ConfigureServices support environment specific versions of the form Configure{EnvironmentName} and Configure{EnvironmentName}Services:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    public void ConfigureStagingServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }

        if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
        {
            app.UseExceptionHandler("/Error");
        }

        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();
    }

    public void ConfigureStaging(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (!env.IsStaging())
        {
            throw new Exception("Not staging.");
        }

        app.UseExceptionHandler("/Error");
        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();
    }
}

Additional resources