microsoft / iis-docker

Dockerfile for IIS
https://hub.docker.com/r/microsoft/iis/
MIT License
292 stars 129 forks source link

Question: How to use environments in IIS websites / web apps? #2

Closed StefanScherer closed 7 years ago

StefanScherer commented 8 years ago

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 from docker 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 as ENTRYPOINT (or CMD) and set these envs as system environments before starting the Windows Service (IIS must be set to manual before I think).

shirhatti commented 8 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

friism commented 8 years ago

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

shirhatti commented 8 years ago

@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
glennc commented 8 years ago

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?

shirhatti commented 8 years ago

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

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.

glennc commented 8 years ago

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?

pan-wang commented 8 years ago

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.

glennc commented 8 years ago

@pan-wang Sounds like an easy solution, I like it :).

rfeltis-alaska commented 7 years ago

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.

richlander commented 7 years ago

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, ...)?

ralphflywheel commented 7 years ago

@richlander our image is based off of the microsoft/iis:windowsservercore family. We are deploying an ASP.NET WebAPI project.

richlander commented 7 years ago

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.

ralphflywheel commented 7 years ago

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

richlander commented 7 years ago

Thanks for the feedback! I suspect you nailed it.

charlessolar commented 7 years ago

:+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

sharushetty commented 7 years ago

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.

shirhatti commented 7 years ago

@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.

kellybirr commented 7 years ago

Is there any ETA for the updated ServiceMonitor.exe? I looked today but still only see the initial version from 8 months ago.

Thanks!

StefanScherer commented 7 years ago

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

shirhatti commented 7 years ago

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.

ChiefWiggum commented 7 years ago

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

seanturner83 commented 7 years ago

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.

pan-wang commented 7 years ago

servicemonitor is very simple program. will make it open source soon so that people can extend it.

shirhatti commented 7 years ago

This has been added in the July 2017 updates to the microsoft/iis image.

nareshkhatri81 commented 6 years ago

@shirhatti can you point to image which has that bug fixed ? does microsoft/iis:windowsservercore-ltsc2016 has that bug fixed ?

Thanks, Naresh

shirhatti commented 6 years ago

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

tburnett80 commented 6 years ago

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.