Runtime: implement Environment.IsDocker

Created on 10 Jun 2018  Â·  10Comments  Â·  Source: dotnet/runtime

_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_

area-System.Runtime 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?

All 10 comments

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:

  • The runtime/BCL has currently no need of being aware of that environment variable, as containarization is expected to be transparent. Most applications would only ever need to know the value of that variable if it somehow affected the behavior of the runtime.
  • If the framework does add a helper for reading this one environment variable, should it also start adding helpers for many other environment variables ? (If so, where is the limit ?)
  • By exposing a property such as 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.
  • In the same way that a regular application is not supposed to know whether it's running inside a VM, it shouldn't expected to know whether it's running inside a container.
  • Speaking of containers, if such a property were ever to be introduced, I'd sure hope it would be called something like 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:

  1. Per discussion above it doesn't deserve an API.
  2. The question itself is more related to containers than to CoreFx (quick search gets me to this stack overflow thread).
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sahithreddyk picture sahithreddyk  Â·  3Comments

EgorBo picture EgorBo  Â·  3Comments

chunseoklee picture chunseoklee  Â·  3Comments

matty-hall picture matty-hall  Â·  3Comments

jzabroski picture jzabroski  Â·  3Comments