Reputation: 1309
In Startup.cs file I have
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
There is appsettings.json file with configurations. Like :
{
"Log" : {
"Type" : "value from appsettings.json"
}
}
reloadOnChange
set to true
, so, when I change appsettings.json then I get immediately a new value of log type in my program.
But I'm using Docker with docker-compose and pass a value of setting by env variables. My docker-compose.override.yml file is:
version: '3.7'
services:
myservice:
environment:
ASPNETCORE_ENVIRONMENT: Development
Log__Type: "value from docker-compose"
To run I use `docker-compose up. Now my app has value "value from docker-compose" for log type.
Question: Are there any ways to change a value of env variable (Log__Type
) at runtime (without restarting docker container) and reload configuration in my app as it has done with reloadOnChange
and appsettings.json?
I tried to connect to the container (docker exec
) and set a new value of env variable
printenv Log__Type // -> value from docker-compose
export Log__Type=new value
printenv Log__Type // -> new value
but my app didn't reload configuration and still shows log type "value from docker-compose".
Could you please advise how to change settings at runtime using docker? Or explain why there is only reload when the file has changed but not env variable.
Upvotes: 10
Views: 4004
Reputation: 71
so what you want to do is read weather a file has changed or not during runtime? you can use a FileSystemWatcher to detect when the file has been changed or edited, so in a sense you can, but detecting weather or not a specific variable has changed is a bit more messy, because you'd only be able to detect when the entire file has had a change to it, and then check if the wanted var has changed yourself.
but if we're talking about the app reciving a new environment change during runtime, you can use a hacky solution, using a NamedPipeStream you could send environment changes by either starting another process to tell the main one to update Var X to Y or by like mentioning earlier but instead having a sub process detecting it and sending it back up the chute.
NamedPipeStream Server MSD NamedPipeStream Client MSD
Upvotes: 0
Reputation: 158848
Are there any ways to change a value of env variable at runtime (without restarting docker container)
No. (And even a restart isn't enough: you need to delete and recreate the container.)
This follows the ordinary Unix model. A process can set the initial environment for its child process, but once it's exec'd the child, it has no more control over the environment any more. docker exec
launches a new process in the container namespace and so if you change an environment variable there it will only affect that process and not the main container process.
There are a significant number of options that can only be set during the initial docker run
command. This includes environment variables, and also includes volume mounts and published ports. Critically, it also includes the underlying image: if you ever have a new build of your application, or need to update the underlying OS distribution for a security issue, you will be forced to delete and recreate your container. In my experience docker rm
is extremely routine, and you should plan for it to happen regularly.
Upvotes: 7