Closed StefanScherer closed 7 years ago
While surfacing environment variables to be used by IIS apps is a reasonable ask that we NEED to address, I'm not convinced that ServiceMonitor.exe
is the best place to surface it.
Including a few folks who might have an opinion on this @glennc @staceyhaffner @richlander @pan-wang
An alternative would be for the image to run a web.config transform on start that transports Docker environment variables into web.config App Settings and connectionstrings. I suggested that here: https://github.com/Microsoft/Virtualization-Documentation/issues/401#issuecomment-251293311
@friism I want to make sure you are not conflating IIS configuration with ASP.NET configuration. We still need a way to say, set up environment variables for use in your PHP application. While what you bring up is important, it is a slightly different problem and I think the solution to that problem will live in the ASP.NET base image.
@StefanScherer you should just be able to run appcmd.exe
to set an environment variable in your Dockerfile. However, we still need a way to flow settings from docker run -e VAR=val
to IIS.
RUN appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='DefaultAppPool'].environmentVariables.[name='foo',value='bar']" /commit:apphost
Why the desire for this not to be something that ServiceMonitor.exe
does? Is it not the job of ServiceMonitor to smooth exactly this sort of problem?
I'm afraid that auto-magically flowing environment variables would make this rather fragile. A few questions that pop up just off the top of my head
DefaultAppPool
?In my opinion, ServiceMonitor.exe
should remain a lightweight shim process. I'd be happy to try and build this as a standalone .exe
let people try it out and then look at merging this into ServiceMonitor.exe
.
However, this is just me thinking out loud at this point and I'm definitely open to suggestions.
I have never thought of ServiceMonitor
as a lightweight shim. I have thought of it as the way to use IIS inside a container in the way I would expect/want an entrypoint to work. Is that just me?
as dock command will set the environment variable, we only need to restart the WAS service to adopt the variable. One simple solution is to disable WAS server from default iis container image.
@pan-wang Sounds like an easy solution, I like it :).
Any update on this? We are attempting to carry the same Docker image through multiple environments, but send in configuration changes as environment variables. If we have to modify our Dockerfile, then we have to build separate images for each environment. Not ideal.
A little off-topic ...
@rfeltis-alaska I'm curious ... are you using the microsoft/iis image directly? What type of application are you deploying (ASP.NET, PHP, ...)?
@richlander our image is based off of the microsoft/iis:windowsservercore family. We are deploying an ASP.NET WebAPI project.
Any reason to not use the aspnet image? We believe that many people are following your pattern and are wondering why. It's not a problem, just wondering why the aspnet image isn't a compelling option for you.
I think discoverability is a bit of a problem. I didn't know that there was an aspnet image. Most tutorials out there start you off with microsoft/iis. That being said, there isn't a ton of value being added from the aspnet Dockerfile. We already need to add more IIS features than the aspnet image brings (such as App Initialization) so we're going to be making an intermediate container anyway. I think we could go either way.
Here are the first two relevant Google searches for "docker iis":
http://blog.alexellis.io/run-iis-asp-net-on-windows-10-with-docker/
https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-images
Thanks for the feedback! I suspect you nailed it.
:+1: I'll need a way to pass environmental variables into my microsoft/iis docker image for configs across multiple environments.
This appcmd.exe
solution gets a variable set but -e
doesn't work, which is kinda the whole point
I'm facing the exact same problem as @rfeltis-alaska and @volak. Do we have any solution to this problem yet?
Currently I'm setting the environment variable by putting the below line within my docker file:
RUN setx /m Env_Variable1 123456
But the above environment variable's value is client specific and I would like to know if there is a way I can set this value during docker run and not hard code it within the docker file which would mean I have to create a new docker image for each of our clients.
@volak @sharushetty I understand that the current model where you cannot pass environment variables directly from docker run is extremely limiting. As a short-term solution, we'll update ServiceMonitor.exe
to automatically flow the environment variables.
In the meanwhile, we have also been making investments around allowing you to run w3wp.exe
standalone without the burden of WAS or W3SVC. In future, we would like to move people to this model instead.
Is there any ETA for the updated ServiceMonitor.exe? I looked today but still only see the initial version from 8 months ago.
Thanks!
Just to connect the dots. There is a similar tool to ServiceMonitor.exe which has been open sourced a few weeks ago: https://github.com/Ticketmaster/spinner
We have a new version version of ServiceMonitor
that promotes environment variables to the DefaultAppPool. See MicrosoftDocs/Virtualization-Documentation#41
If you folks could give it a try, we'd appreciate the feedback.
I've changed our dockerfile
to copy the newer version over the existing one from the Microsoft/IIS image and it worked like a charm. We use it to pass in the ASPNETCORE_ENVIRONMENT
variable.
In case anyone is interested: Until now our solution for our AspNetCore app that runs behind an IIS was to add a 3-letter prefix to the docker hostnames (--hostname="PRD-{{.Node.ID}}"
) and to check for that prefix in the Startup.cs
and then set the environment. Not ideal, but working as a temporary fix:
public Startup(IHostingEnvironment env)
{
if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")))
{
var envName = Environment.MachineName.Substring(0, 3).ToLower();
env.EnvironmentName = envName == "stg" ? "Staging": envName == "prd" ? "Production" : "Development";
}
...
Thanks for the fix
Seems to do exactly what it says on the tin. As mentioned elsewhere, open sourcing this would be good, then people (e.g. Ticketmaster) wouldn't need to roll their own to improve it and contribute back to the community.
servicemonitor is very simple program. will make it open source soon so that people can extend it.
This has been added in the July 2017 updates to the microsoft/iis
image.
@shirhatti can you point to image which has that bug fixed ? does microsoft/iis:windowsservercore-ltsc2016 has that bug fixed ?
Thanks, Naresh
Yes, microsoft/iis:windowsservercore-ltsc2016
does have the new ServiceMonitor. In fact, every image since July 2017 has featured the updated ServiceMonitor.
If you are still seeing issues, please open a new bug
I couldn't seem to get this to work. I eventually had to override the entry point to run a powershell script for initializing on run. We are in the process of moving to core but have to stick with Framework for the near future for some of our stuff and moving to Docker over Nuget for Octopus deployments was painful for Framework projects.
my init script would set the -e variables as machine level vars inside the container, perform web.config transforms based on the ASPNET_ENVIRONMENT variable passed ( from this article ASP.NET Web.config Transforms in Docker Containers ) and because we can no longer substitute variables from Octopus on deployment inside a web.config that is now in the image, I perform a find and replace for matching ENV vars in the web.config. After that I start ServiceMonitor and let it work normally.
Things are definitely easier once you can move your stuff to Core, but where there is a will, there is a way with Framework.
One question that some of the Docker Captains are discussing at the moment is how to set some environment variables eg. from the
ENV
or fromdocker run -e VAR=val
to be used in IIS web apps.As IIS is running as a Windows service it does not catch up these environments. What about using such
ServiceMonitor.exe
asENTRYPOINT
(orCMD
) and set these envs as system environments before starting the Windows Service (IIS must be set to manual before I think).