发布到IIS,设置环境变量

时间:2015-06-25 11:31:33

标签: iis asp.net-core visual-studio-2015 asp.net-core-mvc

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

Asp.net vNext early beta publish to IIS in windows server

How to configure an MVC6 app to work on IIS?

问题是,即使在IIS上运行,网络应用仍然使用值env.EnvironmentName的{​​{1}}。

另外,我想在同一台服务器上运行同一个Web(Staging,Production)的两个版本,所以我需要一个方法来为每个Web单独设置变量。

怎么做?

17 个答案:

答案 0 :(得分:227)

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.

  1. Go to your application in IIS and choose Configuration Editor.
  2. Select Configuration Editor
  3. Choose system.webServer/aspNetCore (RC2 and RTM) or system.webServer/httpPlatform (RC1) in Section combobox
  4. Choose Applicationhost.config ... in From combobox.
  5. Click on enviromentVariables element and open edit window.
  6. Set your environment variables.
  7. Close the window and click Apply.
  8. 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.

答案 1 :(得分:29)

使用< 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 :(得分: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用户更具侵入性。

答案 3 :(得分:16)

经过大量谷歌搜索后,我发现了一个有效的解决方案,包括两个步骤。

第一步是将系统范​​围的环境变量ASPNET_ENV设置为Production并重新启动Windows Server 。在此之后,所有网络应用都获得了“生产”的价值。作为EnvironmentName。

第二步(为了启用价值&#39;暂存和#39;用于登台网络)更难以正常工作,但现在是:

  1. 在服务器上创建新的Windows用户,例如 StagingPool
  2. 对于此用户,使用值&#39; Staging&#39;创建新的用户变量ASPNETCORE_ENVIRONMENT。 (您可以通过以此用户身份登录或通过注册表来执行此操作)
  3. 以IIS管理员身份返回管理员,找到运行Staging Web的应用程序池,并在高级设置中将Identity设置为用户 StagingPool
  4. 同时将加载用户个人资料设置为 true ,以便加载环境变量。 &lt; - 非常重要!
  5. 确保 StagingPool 具有对Web文件夹的访问权限并停止并启动应用程序池。
  6. 现在,临时网站应将EnvironmentName设置为&#39; Staging&#39;。

    更新:在Windows 7+ there is a command中,可以为CMD提示也为指定用户设置环境变量。这输出帮助加样品:

    {{1}}

答案 4 :(得分:14)

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

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

enter image description here

以下内容:

{
  // 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上,与环境变量值无关。

答案 5 :(得分: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

答案 6 :(得分:5)

编辑 applicationHost.config 的@tredder解决方案是在IIS上的虚拟目录中有多个不同的应用程序时可以使用的解决方案。

我的情况是:

  • 我在同一个域下有 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完成了这项工作。

答案 7 :(得分:4)

您需要在一个地方知道什么:

  • 要覆盖任何配置设置的环境变量,它们必须以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

  • 非URL安全的字符可以转义为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
  • 之类的内容

答案 8 :(得分:3)

您还可以使用以下方法将所需的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 :(得分:2)

与其他答案类似,我想确保我的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 }

答案 10 :(得分:2)

除上述选项外,还有其他一些解决方案可以很好地与自动部署配合使用,或者需要进行更少的配置更改。

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>

以上代码将为调试配置或未指定配置添加环境名称为Development。对于任何其他配置,在生成的web.config文件中,环境名称将为Production。更多详细信息here

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

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

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

3。使用dotnet发布的命令行选项

此外,我们可以将属性EnvironmentName作为命令行选项传递给dotnet publish命令。以下命令将在web.config文件中将环境变量包括为Development

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

答案 11 :(得分:1)

只需将<EnvironmentName>添加到您的发布个人资料中并完成它:

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

该信息将复制到 web.config 。 (请勿手动设置 web.config ,因为它会被覆盖。)

来源:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments

答案 12 :(得分:1)

对于那些希望在天蓝色的devops管道中使用此工具的人,可以通过添加PowerShell on target machines任务并运行以下脚本来实现:

$envVariables = (
  @{name='VARIABLE1';value='Value1'},
  @{name='VARIABLE2';value='Value2'}
)

Set-WebConfigurationProperty -PSPath IIS:\ -Location $('mySite') -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value $envVariables

答案 13 :(得分:1)

我知道已经给出了很多答案,但是就我而言,我在项目中添加了web。{Environment} .config版本,并在针对特定环境发布时替换了值。


例如,用于登台(web.Staging.config)

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <location>
        <system.webServer>
            <aspNetCore>
                <environmentVariables xdt:Transform="InsertIfMissing">
                    <environmentVariable name="ASPNETCORE_ENVIRONMENT"
                                         value="Staging"
                                         xdt:Locator="Match(name)"
                                         xdt:Transform="InsertIfMissing" />
                </environmentVariables>
            </aspNetCore>
        </system.webServer>
    </location>
</configuration>

对于发行版或正式版,我将执行此操作(web.Release.config)

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <location>
        <system.webServer>
            <aspNetCore>
                <environmentVariables xdt:Transform="InsertIfMissing">
                    <environmentVariable name="ASPNETCORE_ENVIRONMENT"
                                         value="Release"
                                         xdt:Locator="Match(name)"
                                         xdt:Transform="InsertIfMissing" />
                </environmentVariables>
            </aspNetCore>
        </system.webServer>
    </location>
</configuration>

然后在发布时,我将选择或设置环境名称。它将替换最终的web.config文件中的环境值。

答案 14 :(得分: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.json appsettings.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. 现在只需在 envsettings.json 文件中更改并发布 ASPNETCORE_ENVIRONMENT 即可。

答案 15 :(得分:0)

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

https://github.com/expressiveco/AspnetCoreWebConfigForEnvironment

  • 设置
    • 将.csproj和.user.csproj文件中的部分放入项目文件中。
    • 获取MyAspNetEnvironment.props,web.development.config和web.production.config文件。
  • 配置
    • 相关地更改user.csproj中ASPNETCORE_ENVIRONMENT属性的值。

答案 16 :(得分:0)

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

注意:在我的案例中,Web应用程序是ASP.NET Core 2托管在IIS 10上的Web应用程序。可以通过Configuration Editor中的IIS Manager来完成(请参阅Editing Collections with Configuration Editor,找出在IIS Manager中找到此编辑器的位置。)