发布到IIS,设置环境变量


134

阅读这两个问题/答案,我能够在IIS 8.5服务器上运行Asp.net 5应用程序。

Asp.net vNext早期Beta发布到Windows Server中的IIS

如何配置MVC6应用程序以在IIS上运行?

问题是,即使在IIS上运行,Web应用程序仍在使用env.EnvironmentNameDevelopment

另外,我想在同一台服务器上运行同一Web的两个版本(登台,生产),因此我需要一种方法来分别为每个Web设置变量。

这该怎么做?


4
一个通常具有三个网络环境:开发,登台和生产。Web服务器位于一个环境中。因此,为服务器设置系统环境变量通常不是真正的限制。人们仍然可以使用它Properties\launchSettings.json模拟另一种环境,以便在Visual Studio中进行调试。
奥莱格2015年

Answers:


285

该答案最初是为ASP.NET Core RC1编写的。在RC2中,ASP.NET Core从通用的httpPlafrom处理程序转移到aspnetCore特定的处理程序。请注意,步骤3取决于您所使用的ASP.NET Core版本。

事实证明,可以为ASP.NET Core项目设置环境变量,而不必为用户设置环境变量或创建多个命令条目。

  1. 在IIS中转到您的应用程序,然后选择Configuration Editor
  2. 选择 Configuration Editor
  3. 在组合框中选择system.webServer/aspNetCore(RC2和RTM)或system.webServer/httpPlatform(RC1)Section
  4. Applicationhost.config ...From组合框中选择。
  5. 右键单击enviromentVariables元素,选择'environmentVariables' element,然后选择Edit Items在此处输入图片说明
  6. 设置环境变量。
  7. 关闭窗口,然后单击“应用”。
  8. 完成了

这样,您不必为池创建特殊用户或在中创建额外的命令条目project.json。另外,为每个环境添加特殊命令会破坏“一次构建,多次部署”,因为您必须dnu publish分别针对每种环境调用,而不是一次发布并多次部署生成的工件。

感谢Mark G和tredder,针对RC2和RTM进行了更新。


12
对于步骤3,我system.webServer/aspNetCore改用了。
Mark G

1
系统环境变量在启动时被进程继承。因此,如果在应用程序运行期间更改了一些env变量,则默认情况下将看不到此更改。为了使系统环境更改生效,您至少需要重新启动站点(可能是池甚至是IIS服务),具体取决于IIS创建进程的方式。这需要进行测试。
NickAb

7
通过配置编辑器添加的设置在下一次部署时不会消失吗?
布拉德·加德纳

11
@ brad-gardner如果对Applicationhost.config而不是web.config进行了更改,则更改将在部署之间保留。
NickAb

15
适用于Asp.Net Core 2.0
Frank Cannon

34

<aspNetCore>下的<environmentVariables>部分更新web.config

<configuration>
  <system.webServer>
    <aspNetCore .....>
      <environmentVariables>
        <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
      </environmentVariables>
    </aspNetCore>
  </system.webServer>
</configuration>

或者,为避免在覆盖web.config时丢失此设置,请对applicationHost.config进行类似更改,如@NickAb建议的那样指定站点位置。

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

2
这与您的web.config是项目的一部分并在VCS中进行版本控制的方式有所不同。如果您有多个环境,例如prod,staging,dev,那么您将需要某种方式来转换每个环境的web.config。在IIS中更改ApplicationHost.config仅影响此IIS。这样,您就可以在VCS中拥有单个web.config,并且可以使用特定于IIS的环境变量来覆盖web.config变量。可以使用PowerShelliis.net/learn/manage/powershell/…以编程方式编辑ApplicationHost.config
NickAb '16

感谢@NickAb,它避免了每次部署都必须更新web.config。我已经更新了答案。
Trevor Daniels'6

我在powershell上执行此操作时遇到了麻烦,我一直在获取Target configuration object '/system.webServer/aspNetCore/environmentVariables/environmentVariable is not found ... 正常设置一些变量的方法是这样写的:Set-WebConfigurationProperty -PSPath IIS:\ -location example.com -filter /system.webServer/aspNetCore/environmentVariables/environmentVariable -name ASPNETCORE_ENVIRONMENT -value Staging 我缺少什么?
基督教徒

我回到了我所知道的地方,appcmd改为使用它。
基督教徒

@Christian,请查看以下答案:stackoverflow.com/a/50869935/33533环境变量的名称和值放在哈希表中,因此从您的示例中将是Set-WebConfigurationProperty -PSPath IIS:\ -Location example.com -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = 'Staging' }
Curtis

21

编辑:从RC2和RTM版本开始,此建议已过时。我发现在发行版中完成此任务的最佳方法是针对每种环境在IIS中编辑以下web.config部分:

system.webServer/aspNetCore

编辑environmentVariable条目并添加环境变量设置:

ASPNETCORE_ENVIRONMENT< Your environment name >


作为drpdrp方法的替代方法,您可以执行以下操作:

  • 在您的project.json中,添加将ASPNET_ENV变量直接传递到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"
    }
    
  • 发布时,使用--iis-command选项指定环境:

    dnu publish --configuration Debug --iis-command Staging --out "outputdir" --runtime dnx-clr-win-x86-1.0.0-rc1-update1
    

我发现这种方法比创建额外的IIS用户要少打扰。


11
如果您通过Visual Studio的msdeploy发布。然后,可以将<IISCommand> Staging </ IISCommand>放入.pubxml文件中,即使您无法在发布UI中指定它,它也会使用指定的IIS命令进行部署。
Dean North

@DeanNorth-这是金色的!像冠军一样工作!感谢分享!
S. Rasmussen

17

我的Web应用程序(生产,标记,测试)托管在IIS Web服务器上。因此,不可能依靠ASPNETCORE_ENVIRONMENT操作员的系统环境变量,因为将其设置为特定值(例如STAGING)会对其他应用程序产生影响。

解决方法是,我在visualstudio解决方案中定义了一个自定义文件(envsettings.json):

在此处输入图片说明

具有以下内容:

{
  // Possible string values reported below. When empty it use ENV variable value or Visual Studio setting.
  // - Production
  // - Staging
  // - Test
  // - Development
  "ASPNETCORE_ENVIRONMENT": ""
}

然后,根据我的应用程序类型(生产,暂存或测试),我一致地设置此文件:假设我正在部署TEST应用程序,我将拥有:

"ASPNETCORE_ENVIRONMENT": "Test"

之后,只需在Program.cs文件中检索此值,然后设置webHostBuilder的环境即可:

    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();
        }
    }

请记住在publishOptions(project.json)中包含envsettings.json:

  "publishOptions":
  {
    "include":
    [
      "wwwroot",
      "Views",
      "Areas/**/Views",
      "envsettings.json",
      "appsettings.json",
      "appsettings*.json",
      "web.config"
    ]
  },

此解决方案使我可以自由地将ASP.NET CORE应用程序托管在同一个IIS上,而与envoroment变量值无关。


非常好,我建议的唯一更改是swap var currentDirectoryPath = Directory.GetCurrentDirectory(); 对于var currentDirectoryPath = PlatformServices.Default.Application.ApplicationBasePath; 这是获取当前目录的更安全的方法。
彼得·科塔斯

7
当您必须创建另一层配置来管理框架的配置时,这真是很棒的体验
Kugel

16

经过广泛的谷歌搜索,我找到了一个可行的解决方案,其中包括两个步骤。

第一步是将系统范​​围的环境变量ASPNET_ENV设置为Production并重新启动Windows Server。此后,所有Web应用程序都将其值“ Production”作为EnvironmentName。

第二步(为分段Web启用值“分段”)要正常工作要困难得多,但是这里是:

  1. 创建新的Windows用户,例如服务器上的StagingPool
  2. 为该用户创建新的用户变量ASPNETCORE_ENVIRONMENT,其值为'Staging'(您可以通过以该用户身份登录或通过regedit来执行此操作)
  3. 在IIS管理器中以管理员身份返回,找到正在运行暂存Web的应用程序池,然后在“高级设置”中将“身份”设置为用户StagingPool
  4. 还将“ 加载用户配置文件”设置为true,以便加载环境变量。<-非常重要!
  5. 确保StagingPool具有对该Web文件夹以及“停止并启动应用程序池”的访问权限。

现在,登台站点应该将EnvironmentName设置为“登台”。

更新:在Windows 7+中,有一个命令可以从CMD提示符下为指定用户设置环境变量。这将输出帮助以及示例:

>setx /?

1
似乎在ASP.NET 5 RC1中,环境变量已更改为Hosting:Environment。
Grady Werner

将其部署到Azure Web App时如何将“加载用户配置文件”设置为true?
浦那·甘尚尼

@PunitGanshani据我所知,那里的Web应用程序在蔚蓝的门户“应用程序设置”部分,在那里你可以设置环境键/值对是:azure.microsoft.com/en-us/documentation/articles/...
drpdrp

@GradyWerner对于RC2,他们正在将其更改为ASPNET_ENVIRONMENT(
b.pell

1
@ b.pell看来现在是ASPNETCORE_ENVIRONMENT :)
Mark G

11

您也可以ASPNETCORE_ENVIRONMENT使用以下命令将所需的参数作为参数传递给dotnet publish命令:

/p:EnvironmentName=Staging

例如:

dotnet publish /p:Configuration=Release /p:EnvironmentName=Staging

这将生成具有为项目指定的正确环境的web.config:

<environmentVariables>
  <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>

9

除了上面提到的选项之外,还有其他一些解决方案可以很好地与自动部署一起使用,或者需要更少的配置更改。

1.修改项目文件(.CsProj)文件

MSBuild支持该EnvironmentName属性,该属性可以帮助根据您希望部署的环境设置正确的环境变量。环境名称将在发布阶段添加到web.config中。

只需打开项目文件(* .csProj)并添加以下XML。

<!-- Custom Property Group added to add the Environment name during publish
  The EnvironmentName property is used during the publish for the Environment variable in web.config
  -->
  <PropertyGroup Condition=" '$(Configuration)' == '' Or '$(Configuration)' == 'Debug'">
    <EnvironmentName>Development</EnvironmentName>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' != '' AND '$(Configuration)' != 'Debug' ">
    <EnvironmentName>Production</EnvironmentName>
  </PropertyGroup>

上面的代码将为DevelopmentDebug配置或未指定配置添加环境名称。对于任何其他配置,环境名称将Production在生成的web.config文件中。在这里更多细节

2.在发布配置文件中添加EnvironmentName属性。

我们也可以<EnvironmentName>在发布配置文件中添加该属性。打开位于的发布配置文件。Properties/PublishProfiles/{profilename.pubxml}这将在发布项目时在web.config中设置环境名称。此处有更多详细信息

<PropertyGroup>
  <EnvironmentName>Development</EnvironmentName>
</PropertyGroup>

3.使用dotnet publish的命令行选项

另外,我们可以将该属性EnvironmentName作为命令行选项传递给dotnet publish命令。接下来的命令将包含Developmentweb.config文件中的环境变量。

dotnet publish -c Debug -r win-x64 /p:EnvironmentName=Development


7

要扩展@tredder的答案,您可以使用以下方法更改环境变量 appcmd

分期

%windir%\system32\inetsrv\appcmd set config "staging.example.com" /section:system.webServer/aspNetCore /+environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Staging'] /commit:APPHOST

生产

%windir%\system32\inetsrv\appcmd set config "example.com" /section:system.webServer/aspNetCore /+environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Production'] /commit:APPHOST


这是在未安装IIS的构建服务器上使用Powershell完成相同操作的方法。gist.github.com/markarnott/c4aec1fc544fe89e2bd21f3f00d78933
Mark Arnott

指定“ staging.example.com”或“ example.com”只会将变量应用于那些特定的网站。省略该选项将为服务器上的所有网站创建一个全局变量。
致命狗

6

您需要在一处知道的内容:

  • 要使环境变量覆盖任何配置设置,必须在它们前面加上ASPNETCORE_
  • 如果要匹配JSON配置中的子节点,请:用作分隔符。如果平台不允许在环境变量键中使用冒号,请__改用。
  • 您希望您的设置以结尾ApplicationHost.config。使用IIS配置编辑器将使您的输入被写入应用程序的Web.config-并在下次部署中被覆盖!
  • 为了进行修改ApplicationHost.config,您需要使用appcmd.exe来确保您的修改是一致的。例:%systemroot%\system32\inetsrv\appcmd.exe set config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore /+"environmentVariables.[name='ASPNETCORE_AWS:Region',value='eu-central-1']" /commit:site

  • 网址不安全的字符可以转义为Unicode,例如%u007b左花括号。

  • 列出当前设置(与Web.config中的值结合使用): %systemroot%\system32\inetsrv\appcmd.exe list config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore
  • 如果您运行命令为同一密钥多次设置配置密钥,它将被多次添加!要删除现有值,请使用%systemroot%\system32\inetsrv\appcmd.exe set config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore /-"environmentVariables.[name='ASPNETCORE_MyKey',value='value-to-be-removed']" /commit:site

1
请注意,所做/commit:site的更改已写入web.config,为了将它们保存在ApplicationHost.config其中,应使用/commit:apphost
Angel Yordanov

-section:system.webServer/aspNetCore /-"environmentVariables.(带有减号以删除环境变量)在Azure发布管道期间无法执行。错误是hresult:80070032, message:Command execution failed。但是clear config "Default Web Site/$(webSiteName)" -section:system.webServer/aspNetCore /commit:site效果很好。它清除了网站的整个aspNetCore部分,但这不是问题,因为在发布期间对其进行了参数设置。
oleksa

5

如果您在IIS的虚拟目录中有几个不同的应用程序,则可以通过编辑applicationHost.config来实现@tredder解决方案。

我的情况是:

  • 我在相同的域中确实有API项目和APP项目放置在不同的虚拟目录中
  • 根页面XXX似乎没有将ASPNETCORE_ENVIRONMENT变量传播到其虚拟目录中的子目录中,并且...
  • ...我无法按照@NickAb所述设置虚拟目录中的变量(错误提示,不支持该请求。(在配置编辑器中保存更改期间,来自HRESULT的异常:0x80070032):
  • 进入applicationHost.config并手动创建节点,如下所示:

    <location path="XXX/app"> <system.webServer> <aspNetCore> <environmentVariables> <clear /> <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" /> </environmentVariables> </aspNetCore> </system.webServer> </location> <location path="XXX/api"> <system.webServer> <aspNetCore> <environmentVariables> <clear /> <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" /> </environmentVariables> </aspNetCore> </system.webServer> </location>

然后重新启动IIS就可以了。


5

与其他答案类似,我想确保我的ASP.NET Core 2.1环境设置在所有部署中都能保留,但也仅适用于特定站点。

根据Microsoft的文档,可以在IIS 10中使用以下PowerShell命令在应用程序池上设置环境变量:

$appPoolName = "AppPool"
$envName = "Development"
cd "$env:SystemRoot\system32\inetsrv"
.\appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='$appPoolName'].environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='$envName']" /commit:apphost

不幸的是,我仍然必须使用IIS 8.5,以为我不走运。但是,仍然可以运行简单的PowerShell脚本为ASPNETCORE_ENVIRONMENT设置特定于站点的环境变量值:

Import-Module -Name WebAdministration
$siteName = "Site"
$envName = "Development"
Set-WebConfigurationProperty -PSPath IIS:\ -Location $siteName -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = $envName }

0

为了获得有关错误的详细信息,我必须为相应的应用程序池添加ASPNETCORE_ENVIRONMENT环境变量 system.applicationHost/applicationPools

注意:在我的情况下,该ASP.NET Core 2Web应用程序是托管在上的Web应用程序IIS 10。可以通过Configuration Editorin 来完成IIS Manager(请参阅使用Configuration Editor编辑集合以找出在哪里可以找到此编辑器IIS Manager)。


0

我创建了一个存储库,用于使用Web.config中的环境配置发布IIS。

https://github.com/expressiveco/AspnetCoreWebConfigForEnvironment

  • 建立
    • 将.csproj和.user.csproj文件中的部分放入您的项目文件中。
    • 获取MyAspNetEnvironment.props,web.development.config和web.production.config文件。
  • 组态
    • 相应地更改user.csproj中ASPNETCORE_ENVIRONMENT属性的值。

这似乎无法为问题提供优质的答案。请编辑您的答案以添加此解决方案的整体详细信息,或者只是删除它并将其发布为对该问题的评论。谢谢!
sɐunıɔןɐqɐp

0

我修改了@Christian Del Bianco的答案给出。我现在将绝对更改为.net core 2和上层的程序更改为project.json文件。

  1. 首先,在根目录中创建appsettings.json文件。与内容

      {
         // Possible string values reported below. When empty it use ENV 
            variable value or Visual Studio setting.
         // - Production
         // - Staging
         // - Test
        // - Development
       "ASPNETCORE_ENVIRONMENT": "Development"
     }
    
  2. 然后创建另外两个设置文件appsettings.Development.jsonappsettings.Production.json使用必要的配置。

  3. 添加必要的代码以将环境设置为Program.cs文件。

    public class Program
    {
    public static void Main(string[] args)
    {
        var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    
      ***var currentDirectoryPath = Directory.GetCurrentDirectory();
        var envSettingsPath = Path.Combine(currentDirectoryPath, "envsettings.json");
        var envSettings = JObject.Parse(File.ReadAllText(envSettingsPath));
        var enviromentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();***
    
        try
        {
            ***CreateWebHostBuilder(args, enviromentValue).Build().Run();***
        }
        catch (Exception ex)
        {
            //NLog: catch setup errors
            logger.Error(ex, "Stopped program because of setup related exception");
            throw;
        }
        finally
        {
            NLog.LogManager.Shutdown();
        }
    }
    
    public static IWebHostBuilder CreateWebHostBuilder(string[] args, string enviromentValue) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();
                logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
            })
            .UseNLog()
            ***.UseEnvironment(enviromentValue);***
    

    }

  4. envsettings.json添加到您的.csproj文件中,以复制到发布的目录中。

       <ItemGroup>
            <None Include="envsettings.json" CopyToPublishDirectory="Always" />
        </ItemGroup>
    
  5. 现在,只是改变了ASPNETCORE_ENVIRONMENT,只要你想在envsettings.json文件并公布。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.