I have an ASP.NET site running in a windows docker container. I want to be able to read environment variables defined in the Dockerfile. (And when staring the container.)
I am unable to make it work:
Repro:
Install and configure software required to use windows containers.
Create a new (empty) folder.
Create two files (Dockerfile and default.aspx) in the new folder, with the content described bellow.
Navigate to the empty folder and run
docker build -t test .
(This will create a container image with the name testStart powershell in an interactive container:
docker run -it --rm -e FROM_COMMAND_LINE="From command line" --entrypoint powershell test
You will now be in a powershell prompt inside the container. You can now verify that the environment variables are NOT available in the web-site by fetching the web-page:
$(wget http://localhost/default.aspx -UseBasicParsing).Content
Extract of the result:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables
COMPUTERNAME - 540CA54CDB93<br>
PUBLIC - C:\Users\Public<br>
LOCALAPPDATA - C:\Windows\system32\config\systemprofile\AppData\Local<br>
...
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables - Process
COMPUTERNAME - 540CA54CDB93<br>
PUBLIC - C:\Users\Public<br>
LOCALAPPDATA - C:\Windows\system32\config\systemprofile\AppData\Local<br>
...
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables - User
Path - C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;<br>
TEMP - C:\Windows\system32\config\systemprofile\AppData\Local\Temp<br>
TMP - C:\Windows\system32\config\systemprofile\AppData\Local\Temp<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables - Machine
PROCESSOR_REVISION - 3f02<br>
...
Note that FROM_COMMAND_LINE and FROM_DOCKERFILE are missing.
In the powershell console you can verify that the variables are NOT missing:
PS C:\> $env:FROM_COMMAND_LINE
From command line
PS C:\> $env:FROM_DOCKERFILE
Value from dockerfile
I have also tested to do a iisreset, but it does not change the behaviour.
Have I done something wrong?
Are there other ways to specify environment variables that would make them available to iis inside the container?
Dockerfile:
FROM microsoft/aspnet
ENV FROM_DOCKERFILE Value from dockerfile
ADD default.aspx c:/inetpub/wwwroot/default.aspx
default.aspx:
<% @ Page Language="C#" Trace="false"%>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables
<%
foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) {
Response.Write(string.Format("{0} - {1}<br>\n", de.Key, de.Value));
}
%>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables - Process
<%
foreach (DictionaryEntry de in Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process)) {
Response.Write(string.Format("{0} - {1}<br>\n", de.Key, de.Value));
}
%>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables - User
<%
foreach (DictionaryEntry de in Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User)) {
Response.Write(string.Format("{0} - {1}<br>\n", de.Key, de.Value));
}
%>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx GetEnvironmentVariables - Machine
<%
foreach (DictionaryEntry de in Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine)) {
Response.Write(string.Format("{0} - {1}<br>\n", de.Key, de.Value));
}
%>
Note: I'm currently using Docker version 1.12.2-rc1-beta27.1 (build: 7538) a0eb77a
Environment variables passed to
docker
through-e
are set for the process in the container viaCreateProcess
andlpEnvironment
.They are not set as SYSTEM Variables which would reside in the registry in the
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
hive and hencew3wp.exe
won't pick up the changes even when you runiisreset
.You have a couple of workaround options here:
RUN setx /m VAR val
in your Dockerfile. This would be picked by your IIS Worker Process after you runiisreset
.RUN appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='DefaultAppPool'].environmentVariables.[name='VAR',value='val']" /commit:apphost
.There is a better option available now. Basically if you base your docker on microsoft/aspnet, it will include the latest "ServiceMonitor.exe" which will inject environment variables defined for local process into IIS AppPool. It will be accessible right away without a need to restart IIS process.
There is one hack however, the application pool must be "DefaultAppPool", so you can't create your custom app pools, which should be fine for more deployments.
You can read more about this update here.