How to deal with environment differences when deploying asp.net core application?

帅比萌擦擦* 提交于 2019-11-30 12:17:34

问题


Is there a way to change the environment settings when deploying ASP.NET Core application (like config file transformations using debug/release build)?

What would be the best approach for maintaining multiple environment settings in .NET Core applications (something similar to <appSettings file="local.config"> for local, staging and production)?


回答1:


The central configuration file is the appsettings.json and you can have multiple files, like appsettings.Production.json etc, which will be loaded and override settings from the appsettings.json.

For example

        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .SetBasePath(hostEnv.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{hostEnv.EnvironmentName}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

All you need to get this working is the environment variable for setting the environment type (see documentation here).

You can also have environment variables that override, if you add AddEnvironmentVariables() to your configuration builder. So if you have a appsettings.json of

{
    "Data"  {
         "Default" {
              "ConnectionString" : "..."
         }
    }
}

and want to override that via environment Variable, you'd set up an environment variable called "Data:Default:ConnectionString" and it's value will override the settings in the appsettings.config and appsettings.Production.config (assuming your .AddEnvironmentalVariables() is called after .AddJsonFile() - Last registration with the matching key wins) with the value from the environment variable.

You can find more in the official documentation here.

Update

Since in the comments some understand this as the only way to set the environment, there are many ways to set environment variable (most of it is documented in Use multiple environments in ASP.NET Core), all ultimately boiling down to being an environment variable, just within a different scope:

  1. Environment Variable (globally, Windows cmd.exe set ASPNETCORE_ENVIRONMENT=Development or $Env:ASPNETCORE_ENVIRONMENT = "Development" on powershell, export ASPNETCORE_ENVIRONMENT = Development on linux)
  2. Per command environment variable (i.e. linux: ASPNETCORE_ENVIRONMENT=Production dotnet MyApp.dll)
  3. Docker container, i.e. via docker-compose.yaml

    web:
        environment:
        - ASPNETCORE_ENVIRONMENT=Debugging
    
  4. Docker container via command line docker run -e ASPNETCORE_ENVIRONMENT=Debugging
  5. in IIS via web.config.

    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="true" >
      <environmentVariables>
        <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
      </environmentVariables>
    </aspNetCore>
    
  6. On IIS set it per AppPool (see here)
  7. On Linux via service definition files (see docs)
  8. Azure App Service via Environment variables, can be set per slot and having different slots for Staging, Development, Production and i.e. deploying to staging, doing warm up and swapping with Production
  9. Per execution via dotnet run --launch-profile Development

They all change/set the environment variable in a specific scope (globally, locally to a container, inside the app pool, per execution etc.). Choose one which suits your needs.




回答2:


Using additional appsettings.*.json files is a good way to go. The * fragment can be used to mix in any unique environment property that distinguishes between machines, users or deployment scenarios.

But instead of building your config object from scratch using new ConfigurationBuilder() (as shown in many sources on the web) I recommend another approach. The following code will NOT replace your existing config, but ADD to it:

    public IHostingEnvironment _environment { get; }
    public IConfiguration _configuration { get; }

    public Startup(IConfiguration configuration, IHostingEnvironment environment)
    {
        _environment = environment;

        // use the default config and add config from appsettings.COMPUTERNAME.json (if it exists)
        var builder = new ConfigurationBuilder()
            .SetBasePath(environment.ContentRootPath)
            .AddConfiguration(configuration)
            .AddJsonFile($"appsettings.{System.Environment.GetEnvironmentVariable("COMPUTERNAME")}.json", optional: true);
        _configuration = builder.Build();

    }

Background:

When you create your project based on a dotnet new template, then your project already comes with a useful config that is automatically built through the CreateDefaultBuilder() method. This default config combines information from multiple sources: appsettings.json, appsettings.{Environment}.json, Secret Manager, environment variables, and command-line arguments.

If you completely rebuild the config yourself, you will lose all that magic.

Hint:

In the above example appsettings.COMPUTERNAME.json is only an example. You can compose your own json filename from any data in _environment or System.Environment that clearly discriminates your different development and deployment scenarios.



来源:https://stackoverflow.com/questions/37873964/how-to-deal-with-environment-differences-when-deploying-asp-net-core-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!