_From @cilerler on June 10, 2018 3:32_
According to https://github.com/dotnet/announcements/issues/71 new docker images adds DOTNET_RUNNING_IN_CONTAINER=true
into the environment variables.
Based on that please implement Environment.IsDocker
bool IsDocker => bool.TryParse(Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER"), out bool isDocker) && isDocker;
_Copied from original issue: aspnet/Hosting#1454_
So, if I run a .Net Core application in a Docker container that's not based on one of the microsoft/dotnet images, Environment.IsDocker
will return false
? That doesn't sound like a good design to me.
Such images can be useful either for self-contained applications (which don't need .Net Core runtime, so they don't need to use microsoft/dotnet images), or if I'm manually installing the .Net Core runtime into another image (e.g. because I need multiple tools and I decided that using an image that contains those tools and installing .Net Core manually is better than doing it vice versa).
you have a point, however if that variable is not set in the non-microsoft/dotnet
images that shouldn't be our problem. _(unless there is a better way to determine if the environment is docker or not)_
Consider this like EnvironmentName
. If you won't set the environment name, it will be automatically s set as Production
. So no DOTNET_RUNNING_IN_CONTAINER=true
set we always should get false for Environment.IsDocker
.
But IHostingEnvironment.EnvironmentName
is actually an ASP.NET Core feature whose implementation is slightly more complex than an environment variable:
Basically, Microsoft.AspNetCore.Hosting
decided that a reasonable default was to read all environment variables prefixed by ASPNETCORE_
and treat them as IConfiguration
.
The authors of the ASP.NET Core framework also decided that it was sensible to assume that any real world business application could run over more than one environment, and decided that a global hosting setting named Environment
would be exposed as IHostingEnvironment.EnvironmentName
. (hence ASPNETCORE_ENVIRONMENT
)
This in turn, enabled the framework to automagically run different ConfigureServices
and Configure
methods for different environments, while still allowing the application code to make its own decisions based on the environment name.
This issue, however, seems to be about adding a helper property on System.Environment
for the sole purpose of reading a specific environment variable. I see many issues there:
IsDocker
in the framework, we'd be assuming (and publicizing) that somehow, any .NET application would always be able to realiably assert whether its running on Docker. But, as explained by @svick, that cannot be guaranteed with an environment variable.IsContainerized
rather than IsDocker
😉Generally, anything you might be hopping to achieve by "knowing you are running inside of a container" can be easily achieved by changing the configuration of your application, either from inside the container image (e.g. Dockerfile) or when starting the container.
All that made me wonder why the folks at dotnet-docker decided to introduce such an environment variable…
So, I looked up a bit and found out that the environment variable DOTNET_RUNNING_IN_CONTAINER
was introduced for development purposes: https://github.com/dotnet/dotnet-docker/pull/420.
As it turns out, they wanted to enable developers to run their code inside a docker container while developping in the IDE of their choice.
So, in this very specific scenario, the DOTNET_RUNNING_IN_CONTAINER
environment variable is used to assign different output directories to the IDE and the dotnet watch
command running inside the container, so that they don't conflict with eachother. (see samples/aspnetapp/Directory.Build.props for an example)
That might be one of the rare cases where you're actually needing to know that the code inside the container is inside the container… It's a clever trick, but I'm a bit sad to see this variable ends up exposed in production containers.
@GoldenCrystal as you may see in first post I posted it in to the aspnet/Hosting#1454 where I believe it should be handled. However @Tratcher decided that it should be in here.
I truly see your points and I agree most of them. All I'm trying to point out is we need a way to identify if it is containerized or not.
We would not add an API on Environment just to wrap some environment variable set in certain Microsoft docker images. That is way too specific and hacky. I agree with @GoldenCrystal .
@cilerler why do you need to know whether your code is in a container?
Troubleshooting purpose. If you are not the party who deploy your own code, it is very useful to determine what the environment it is running on.
Is there something else about the environment that can be queried to hint that you are in a container?
I found some interesting parallels in the VM world:
https://stackoverflow.com/questions/498371/how-to-detect-if-my-application-is-running-in-a-virtual-machine
@cilerler - Isn't that something you could ask your client about? For that matter, if it's a container, it might be possible to ask for the docker script or the image itself, which would tell you additional things about their environment, too.
For the most part, though, I would probably class container/not-a-container pretty low on the totem pole as compared to libraries installed/permissions/OS, that sort of thing. Errors are usually going to come from farther up the stack.
I appreciate for the effort @Tratcher. Right now, I'm dealing with it through environment variable and relying on people going to update it manually.
@Clockwork-Muse That is exactly how I have been handling this issue. I just thought that now we have an official way to identify that but it seems to me we do not...
Closing this question:
Most helpful comment
We would not add an API on Environment just to wrap some environment variable set in certain Microsoft docker images. That is way too specific and hacky. I agree with @GoldenCrystal .
@cilerler why do you need to know whether your code is in a container?