passing docker environment variables to .net core

Viewed 34147

I've followed this article and the code on the github doesn't compile, tutorial is outdated I think. (Configuration = builder.Build();) throws error. So how can I access env passed from docker?


docker-compose

  myproj:
    image: mcr.microsoft.com/dotnet/core/sdk:2.2
    restart: on-failure
    working_dir: /MyProj
    command: bash -c "dotnet build MyProj.csproj && dotnet bin/Debug/netcoreapp2.2/MyProj.dll"
    ports:
      - 5001:5001
      - 5000:5000
    volumes:
      - "./MyProj:/MyProj"
    environment:
      DATABASE_HOST: database
      DATABASE_PASSWORD: Password

Startup.cs

public Service()
{
    Environment.GetEnvironmentVariable("DATABASE_PASSWORD"); // null
}

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.Run(async (context) =>
    {
        context.Response.WriteAsync("Hello World!");
    });
}
4 Answers

The standard approach to access environment variables in a .NET Core application is to use the static method

public static string GetEnvironmentVariable (string variable);

So in your case irrespective of what you pass either in the docker run command or through the launch settings file just use this method . As an example for getting the Database password use this

string dbPassword = Environment.GetEnvironmentVariable("DATABASE_PASSWORD");

Additionally be sure to define the environment variables part of the dockerfile by adding the line

ENV DATABASE_PASSWORD some_default_value_or_can_be_empty

You can pass env variable in build argument. E.g.

--build-arg ASPNETCORE_ENVIRONMENT=Development

Use below variable to set value:

ASPNETCORE_ENVIRONMENT

Code:

var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

You can use above variable in your code for environment name .

You could read the values with IConfiguration which all done for you by default. If you have configured your host with defaults in Program.cs, then it will load the configuration in the following order

  1. appsetting.json
  2. appsettings..json
  3. secret.json
  4. environment variables
  5. cli args

For example, you could have a class

    public class DatabaseSettings
    {
        public string Host { get; set; }
        public string Password { get; set; }
    }

then in your Startup.cs you can read the values and bind them to a DatabaseSettings object.

var credentials = Configuration.GetSection("Database").Get<DatabaseSettings>();

Note: Your environment variables must have double underscores to separate between the key and the value section.

For example, if you were to pass this from appsettings.json or appsettings.Development.json file, this hierarchical JSON object

  "Database": {
    "Host": "address",
    "Password": "password" 
  }

Can be also represented when flattened like this

"Database:Host":"address",
"Database:Password":"Password"

Or when passed as environment variable can be done as

Database__Host=address
Database__Password=password

Remember, you need double underscore.

If anyone uses Docker-compose.yml environment variables instead of appsettings.json add the following code to IHostBuilder

string someVariable = Environment.GetEnvironmentVariable("Environment Variable Name");

Related