Publish to IIS, setting Environment Variable
Solution 1
This answer was originally written for ASP.NET Core RC1. In RC2 ASP.NET Core moved from generic httpPlafrom handler to aspnetCore specific one. Note that step 3 depends on what version of ASP.NET Core you are using.
Turns out environment variables for ASP.NET Core projects can be set without having to set environment variables for user or having to create multiple commands entries.
- Go to your application in IIS and choose
Configuration Editor
. - Select
Configuration Editor
- Choose
system.webServer/aspNetCore
(RC2 and RTM) orsystem.webServer/httpPlatform
(RC1) inSection
combobox - Choose
Applicationhost.config ...
inFrom
combobox. - Right click on
enviromentVariables
element, select'environmentVariables' element
, thenEdit Items
. - Set your environment variables.
- Close the window and click Apply.
- Done
This way you do not have to create special users for your pool or create extra commands entries in project.json
.
Also, adding special commands for each environment breaks "build once, deploy many times" as you will have to call dnu publish
separately for each environment, instead of publish once and deploying resulting artifact many times.
Updated for RC2 and RTM, thanks to Mark G and tredder.
Solution 2
Update web.config with an <environmentVariables> section under <aspNetCore>
<configuration>
<system.webServer>
<aspNetCore .....>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>
Or to avoid losing this setting when overwriting web.config, make similar changes to applicationHost.config specifying the site location as @NickAb suggests.
<location path="staging.site.com">
<system.webServer>
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
<location path="production.site.com">
<system.webServer>
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
Solution 3
You could alternatively pass in the desired ASPNETCORE_ENVIRONMENT
into the dotnet publish command as an argument using:
/p:EnvironmentName=Staging
e.g.:
dotnet publish /p:Configuration=Release /p:EnvironmentName=Staging
This will generate out the web.config with the correct environment specified for your project:
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
Solution 4
Edit: as of RC2 and RTM releases, this advice is out of date. The best way I have found to accomplish this in release is to edit the following web.config sections in IIS for each environment:
system.webServer/aspNetCore
:
Edit the environmentVariable entry and add an environment variable setting:
ASPNETCORE_ENVIRONMENT
: < Your environment name >
As an alternative to drpdrp's approach, you can do the following:
-
In your project.json, add commands that pass the ASPNET_ENV variable directly to Kestrel:
"commands": { "Development": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Development", "Staging": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Staging", "Production": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Production" }
-
When publishing, use the
--iis-command
option to specify an environment:dnu publish --configuration Debug --iis-command Staging --out "outputdir" --runtime dnx-clr-win-x86-1.0.0-rc1-update1
I found this approach to be less intrusive than creating extra IIS users.
Solution 5
I have my web applications (PRODUCTION, STAGING, TEST) hosted on IIS web server. So it was not possible to rely on ASPNETCORE_ENVIRONMENT operative's system enviroment variable, because setting it to a specific value (for example STAGING) has effect on others applications.
As work-around, I defined a custom file (envsettings.json) within my visualstudio solution:
with following content:
{
// Possible string values reported below. When empty it use ENV variable value or Visual Studio setting.
// - Production
// - Staging
// - Test
// - Development
"ASPNETCORE_ENVIRONMENT": ""
}
Then, based on my application type (Production, Staging or Test) I set this file accordly: supposing I am deploying TEST application, i will have:
"ASPNETCORE_ENVIRONMENT": "Test"
After that, in Program.cs file just retrieve this value and then set the webHostBuilder's enviroment:
public class Program
{
public static void Main(string[] args)
{
var currentDirectoryPath = Directory.GetCurrentDirectory();
var envSettingsPath = Path.Combine(currentDirectoryPath, "envsettings.json");
var envSettings = JObject.Parse(File.ReadAllText(envSettingsPath));
var enviromentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();
var webHostBuilder = new WebHostBuilder()
.UseKestrel()
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseContentRoot(currentDirectoryPath)
.UseIISIntegration()
.UseStartup<Startup>();
// If none is set it use Operative System hosting enviroment
if (!string.IsNullOrWhiteSpace(enviromentValue))
{
webHostBuilder.UseEnvironment(enviromentValue);
}
var host = webHostBuilder.Build();
host.Run();
}
}
Remember to include the envsettings.json in the publishOptions (project.json):
"publishOptions":
{
"include":
[
"wwwroot",
"Views",
"Areas/**/Views",
"envsettings.json",
"appsettings.json",
"appsettings*.json",
"web.config"
]
},
This solution make me free to have ASP.NET CORE application hosted on same IIS, independently from envoroment variable value.
Related videos on Youtube
drpdrp
Updated on July 22, 2022Comments
-
drpdrp almost 2 years
Reading these two questions/answers I was able to run an Asp.net 5 app on IIS 8.5 server.
Asp.net vNext early beta publish to IIS in windows server
How to configure an MVC6 app to work on IIS?
The problem is that the web app is still using
env.EnvironmentName
with valueDevelopment
even when run on IIS.Also, I want to run two versions of the same Web (Staging, Production) on the same server, so I need a method to set the variable for each Web separately.
How to do this?
-
Oleg over 8 yearsOne have typically three network environments Development, Staging and Production. The web server is in one the environment. Thus setting of system environment variable for the server is not a real restriction typically. One can still use
Properties\launchSettings.json
to simulate another environment for debugging in Visual Studio.
-
-
Grady Werner over 8 yearsIt appears that in ASP.NET 5 RC1, the environment variable was changed to Hosting:Environment.
-
GeekzSG over 8 yearsHow do we set "Load User Profile" to true when we deploy this to Azure Web App?
-
drpdrp over 8 years@PunitGanshani As I understand, there is a "application settings" section in azure portal for web app where you can set environment key/value pairs: azure.microsoft.com/en-us/documentation/articles/…
-
b.pell over 8 years@GradyWerner For RC2 they're changing it (as of now) to ASPNET_ENVIRONMENT ;-)
-
Dean North about 8 yearsIf you are publishing through visual studio's msdeploy. Then you can put <IISCommand>Staging</IISCommand> in your .pubxml file and it will deploy using the specified IIS command even though you cant specify it in the publish UI.
-
S. Rasmussen about 8 years@DeanNorth - This is golden!! Works like a champ! Thanks for sharing!
-
Mark G almost 8 years@b.pell It appears it's now ASPNETCORE_ENVIRONMENT :)
-
Mark G almost 8 yearsFor step 3 I used
system.webServer/aspNetCore
instead. -
b.pell almost 8 yearsThanks for the head's up. We're in the process of converting to RC2 as I write this.
-
NickAb almost 8 yearsThis is different in a way that your web.config is a part of project and is versioned in VCS. If you have multiple environments, like prod, staging, dev, then you will need some way to transform web.config for each one. Changing ApplicationHost.config in IIS affects this IIS only. So that you can have single web.config in your VCS and environment variables specific to IIS that override web.config variables. ApplicationHost.config can be edited programatically using PowerShell iis.net/learn/manage/powershell/…
-
Trevor Daniels almost 8 yearsThanks @NickAb, that avoids having to update web.config every deploy. I've updated my answer.
-
Christian almost 8 yearsPlease check NickAb answer it is simpler and does not involve special users and global environment variables.
-
Christian almost 8 yearsI'm having trouble with doing this from powershell I keep getting
Target configuration object '/system.webServer/aspNetCore/environmentVariables/environmentVariable is not found ...
Normally to set some variable I would write something like this:Set-WebConfigurationProperty -PSPath IIS:\ -location example.com -filter /system.webServer/aspNetCore/environmentVariables/environmentVariable -name ASPNETCORE_ENVIRONMENT -value Staging
what Im I missing? -
Christian almost 8 yearsI went back to what I knew and used
appcmd
instead. -
Peter Kottas about 7 yearsVery nice, the only change I suggest is swap var currentDirectoryPath = Directory.GetCurrentDirectory(); for var currentDirectoryPath = PlatformServices.Default.Application.ApplicationBasePath; This is much safer way to get the current dir.
-
Coruscate5 about 7 yearsFor reasons unknown, even with the system Environment Var set, if this section is not modified, .NET Core seems to get "stuck" & doesn't respect the machine setting - this was the only thing that worked
-
NickAb about 7 yearsSystem environment variables are inherited by processes at start. So if you change some env variable during run of your application you would not be able to see this changes by default. For system env var changes to take effect you will need at least to restart the site, maybe pool, or even IIS service, depending on how IIS creates processes. This needs to be tested.
-
Coruscate5 about 7 years@NickAb - I restarted the machine, still didn't pick it up. It must have been getting set somewhere during startup, but I can't find where it could have been. Obviously now it is respecting the IIS setting.
-
madoxdev about 7 yearsYou made my day. Thanks
-
Kugel about 7 yearsWhat a great out of the box experience, when you have to create another layer of configs to manage configs of a framework
-
Brad Gardner almost 7 yearsWon't the settings added via the Configuration Editor get wiped out on the next deployment?
-
NickAb almost 7 years@brad-gardner if changes are made to Applicationhost.config instead of web.config, then changes will be persisted between deployments.
-
The Red Pea almost 7 years
-
The Red Pea almost 7 years
-
NickAb almost 7 years@the-red-pea note that in instructions you linked, web.config is changed, not applicationhost.config. Any changes to web.config on specific IIS server will be lost on next deployment. Changes to applicationhost.config are persisted on specific IIS server between deployments.
-
NickAb almost 7 years@the-red-pea you can edit web.config in your project as shown in your second link, but in that case you will have same values for environment variables despite of target IIS server, e.g. both Staging and Production server will have same ASPNETCORE_ENVIRONMENT value if set via web.config in project. In this case, to get different values on different IIS servers you will have to use web.config transformations to change values. on deployment.
-
user3103701 over 6 yearsHere is how to accomplish the same thing with Powershell on a build server without IIS installed. gist.github.com/markarnott/c4aec1fc544fe89e2bd21f3f00d78933
-
Frank Cannon over 6 yearsWorks for Asp.Net Core 2.0
-
Dave Shinkle over 6 yearsThank you for this!
-
aruno almost 6 yearsIs anybody actually using this method for production? it gets blown away every time you deploy! are you creating a web.config file and using transforms or something else? this answer is not great at all :-(
-
sɐunıɔןɐqɐp almost 6 yearsThis does not seem to provide a quality answer to the question. Please either edit your answer adding the overall details of this solution, or just remove it and post it as a comment to the question. Thanks!
-
deadlydog almost 6 yearsSpecifying "staging.example.com" or "example.com" will only apply the variable to those specific websites. Omitting that will create a global variable for all websites on the server.
-
Curtis Buys over 5 years@Christian, check out this answer: stackoverflow.com/a/50869935/33533 The environment variable name and value go in a hash table, so from your example it would be
Set-WebConfigurationProperty -PSPath IIS:\ -Location example.com -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = 'Staging' }
-
Angel Yordanov over 5 yearsnote that with
/commit:site
the changes are written in the web.config, in order to save them in theApplicationHost.config
one should use/commit:apphost
-
colinwurtz almost 5 yearsStep 4 is very key
-
PatsonLeaner over 4 yearsThanks alot @NickAb, you are a day saver! a00% working on my asp.NET Core 2.2 Hosting in IIS 10. Many Thanks
-
oleksa over 4 years
-section:system.webServer/aspNetCore /-"environmentVariables.
(with minus to remove environment variable) fails to be executed during Azure release pipeline. The error ishresult:80070032, message:Command execution failed
. Howeverclear config "Default Web Site/$(webSiteName)" -section:system.webServer/aspNetCore /commit:site
works fine. It clears the whole aspNetCore section for the web site but it is not a problem since it is parametrized during the release. -
Leff over 4 years@colinwurtz even though I set the variable in ApplicationHost.config, IIS manager starts to show it on both Web.config and ApplicationHost.config pages right after webapp publication, although there's no ASPNETCORE_ENVIRONMENT variable set in the application Web.config file. Application gets some kind of "Staging;Staging" or "Production;Production" string as the value of EnvironmentName.
-
colinwurtz over 4 years@Leff is ASPNETCORE_ENVIRONMENT the variable you set in ApplicationHost.config? I think IIS manager forwards anything from ApplicationHost to Web.Config, but it persists that way between deployments/publishes of the site.
-
Leff over 4 years@colinwurtz Yes, I set the variable in ApplicationHost.config using IIS manager. I suppose this behaviour is the bug of IIS 8.5. As far as I know IIS 10 does not act like this. We've decided to configure the variable using separate application pool accounts for a while.
-
JensB over 4 yearsI could not get this to work with Applicationhost.config after having set the Web.config file first and then removing it from web.config. The key was to redeploy as if you just remove the setting from Web.config using the editor it puts a </clear> tag in the file which removes all environment settings. After redeploy, and a new blank web.config it all worked.
-
Just code over 4 yearsYou are saviour bro!
-
c-sharp-and-swiftui-devni over 3 yearsThis doest appear to work in .net core 3.1 its still not set for me.
-
Abhinav Galodha over 3 years@rouge39nin - I tested it and it worked in .net core 3.1. Can you please provide more details on what you tried and what is your hosting method?
-
Priyank Panchal over 3 yearsThis is exactly what I was looking for. Thank you.
-
Muflix over 3 years@NickAb I just tried to change
ASPNETCORE_ENVIRONMENT
on the fly when the app was running and the change applied immediately, so no restart was needed. Alsoappsettings.<environment>.json
was also reloaded immediately :-) (asp .net core 3.1.8 and IIS 10) -
JustAMartin about 3 yearsGood idea. I prefer setting every variable specific to the environment instead of piggybacking everything onto ASPNETCORE_ENVIRONMENT and environment JSON files. This way app pool env variables can be controlled by system admins who do not want to deal with JSON and also do not want to store production access data in JSON files. Also, you do not want to commit your production env data in Git for every team developer to see.
-
makinyelure about 2 yearsThe assertion that "So it was not possible to rely on ASPNETCORE_ENVIRONMENT operative's system enviroment variable," might not be correct. Each application has it's own pool so there is nothing stopping you from setting the environment per app.