32

I am running a .NET Core app in Docker (in Kubernetes), passing environment variables to the Docker container and using them in my app.

In my .NET Core app I have the following C# class:

public class EnvironmentConfiguration
{
    public string EXAMPLE_SETTING { get; set; }
    public string MY_SETTING_2 { get; set; }
}

And I setup my appsettings as such:

config.
    AddJsonFile("appsettings.json").
    AddJsonFile($"appsettings.docker.json", true).
    AddEnvironmentVariables();  

DI setup:

services.Configure<EnvironmentConfiguration>(Configuration);

And in my Controller I use it as such:

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/my")]
public class MyController : Controller
{
    private readonly IOptions<EnvironmentConfiguration> _environmentConfiguration;

    public MyController(IOptions<EnvironmentConfiguration> environmentConfiguration)
    {
        _environmentConfiguration = environmentConfiguration;
    }
}       

I run docker:

docker run -p 4000:5000 --env-file=myvariables

The file myvariables looks like this:

EXAMPLE_SETTING=example!!!
MY_SETTING_2=my-setting-2!!!!

This works. I can use my _environmentConfiguration and see that my variables are set.

However... I would like to merge environment variables with appsettings so that the values from appsettings are used as fallback when environment variables are not found. Somehow merging these two lines:

services.Configure<EnvironmentConfiguration>(settings => Configuration.GetSection("EnvironmentConfiguration").Bind(settings));
services.Configure<EnvironmentConfiguration>(Configuration);

Is this somehow possible?

My fallback plan is to inherit from the EnvironmentConfiguration class and use a separate DI to have two separate configurations injected and then merge them "manually" in code but this solution is undesirable.

1
  • I am looking into achieving something like this, @Marcus, would you be able to add dockerfile to the question for my reference? It would be nice if you could 2 versions, with env file and with env separately listed. Many thanks Commented Apr 17, 2020 at 14:14

1 Answer 1

67
config.
    AddJsonFile("appsettings.json").
    AddJsonFile("appsettings.docker.json", true).
    AddEnvironmentVariables();

is actually enough to override appsettings values using environment variables.

Let's say you have the following in your appsettings.json file;

{
  "Logging": {
      "Level": "Debug"
  }
}

you can override value of Logging.Level by setting the environment variable named Logging:Level to the value of your preference.

Be aware that : is used to specify nested properties in environment variable keys.

Also note: from docs;

If a colon (:) can't be used in environment variable names on your system, replace the colon (:) with a double-underscore (__).

Sign up to request clarification or add additional context in comments.

5 Comments

Double underscore really solved my problem with environment variables in docker
Double underscore is really the way to go... also when deploying in azure container instances where you want to pass nested configuration values.
Does the order of this chain affect which source takes precedence? If we were to rearrange the code above to config.AddEnvironmentVariables().AddJsonFile("appsettings.json").AddJsonFile($"appsettings.docker.json", true);, would values present in appsettings.docker.json take priority over values in the other two sources since it was called last?
I've just been caught out by ordering - put AddEnvironmentVariables() as the last call or it doesn't work!!!
Could you add an example of appsettings file and dockerfile for completeness? That will help people (like me) understand the actual setup easily. It would be great if you could add a docker command example showing how to run that image with setting a variable. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.