5

I have a .NET Core Web API and I am trying to find out how to use ENV variables to configure keys in my appsetttings.json so I can then populate with data when creating a Docker container.

So far I have managed to inject IOptions<> into my test controller and I was able to debug the values, which were NULL because the app is currently not running in a container just yet.

Test controller:

namespace TestWebApplication.Controllers
{
    [ApiController]
    [Route("api/")]
    public class TestController : ControllerBase
    {
        private readonly IOptions<EnvironmentConfiguration> _environmentConfiguration;

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

        [HttpGet]
        [Route("testmessage")]
        public ActionResult<string> TestMessage()
        {
            var test = _environmentConfiguration.Value;

            return Ok($"Value from EXAMPLE_1 is {test.EXAMPLE_1}");
        }
    }
}

Environment configuration:

namespace TestWebApplication.Models
{
    public class EnvironmentConfiguration
    {
        public string EXAMPLE_1 { get; set; }
        public string EXAMPLE_2 { get; set; }
     }
}

After following some older tutorials I noticed I actually never needed to put any code in ConfigureServices for this to work.

For example, lets say I have this part of my appsettings.json:

"eureka": {
    "client": {
      ......
    },
    "instance": {
      "port": "xxxx",
      "ipAddress": "SET THIS WITH ENV",
    }
  }

How could I set an environment variable to populate the ipAddress so when I go to Docker, I run something like this:

docker run .... -e EXAMPLE_1 -e IP_ADDRESS ....

4
  • 2
    You might need to add configuration.AddEnvironmentVariables() in your application startup, see learn.microsoft.com/en-us/dotnet/api/… Commented Mar 4, 2020 at 12:52
  • Is there any reason why you can't store them in environment-specific appsettings files? I believe it's fairly standard to have, for example, appsettings.development.json and appsettings.production.json. jerriepelser.com/tutorials/airport-explorer/basic/… Commented Mar 4, 2020 at 14:39
  • @SamWalpole it's common practice to use environment variables too, that's why AddEnvironmentVariables() is added by default by the host builder, and overrides the values set by the settings files. In container environments configuration is passed as env variables from the host to the containers. Commented Mar 4, 2020 at 17:19
  • @SamWalpole a settings file can only change during deployment. An orchestrator though can change settings at runtime and possibly restart containers as needed to get them to run with the new settings, eg all at once, in waves etc Commented Mar 4, 2020 at 17:20

1 Answer 1

7

For instance you have a section in appsettings.json:

{
    "Section1" : {
        "SectionA": {
            "PropA": "A",
            "PropB": "B"
        }
    }
}

and a class:

public class SectionA
{
    public string PropA { get; set; }
    public string PropB { get; set; }
}

In Startup.cs map class to section to be able to inject IOptions<SectionA>:

services.Configure<SectionA>(Configuration.GetSection("Section1:SectionA"));

Then you can override properties of SectionA using this naming convention for environment variables: Section1__SectionA__PropA.

Also read this https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#keys

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

16 Comments

Thanks, I'll give that a try. Its been mentioned above to include this: configuration.AddEnvironmentVariables() in Startup.cs. Is this necessary with your example? If so where does it go?
@user1574598 No, if you use Host.CreateDefaultBuilder it's already there.
Great, yes I have Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); in my Program.cs. Also whats the best way to debug this so I know values are being set/overriden? Inspect the SectionA class maybe whist running in a container via Visual Studio?
@user1574598 You can just write SectionA object into log (standard output i.e. console) in place where you inject IOptions<SectionA>. Then just read container logs.
@user1574598 If it works for you mark my answer as correct.
|

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.