Aspnetcore: VSでAspNetCoreプロジェクトのweb.config変換を有効にする

作成日 2017年05月01日  ·  91コメント  ·  ソース: dotnet/aspnetcore

私はweb.configのファンではありませんが、AspNetCoreアプリをIISに公開した経験は本当に貧弱です。

AspNetCoreの構成システムは、さまざまな構成をロードして適用できるASPNETCORE_ENVIRONMENT変数を中心に展開されます。

特定のデプロイメントにこの変数を設定することは悪夢であり、これをどのように行うかについては多くの混乱があるようです。

問題の核心は2つの問題に要約されるようです:

1)VSのASP.NET Coreプロジェクトではサポートされていないことがわかっているため、web.config変換
2)ASPNETCORE_ENVIRONMENTを変更する唯一の合理的な方法は、web.configを使用することです。

グローバルASPNETCORE_ENVIRONMENTを設定することは、単一サーバー上のすべてのサイトに設定されるため、オプションではありません。 web.configは、以前は自己完結型の構成でした。 グローバル環境変数へのこの依存関係は、IISのユースケースでは適切ではありません。

全体として、AspNetCoreに移行する私のような多くの開発者は、既存のインフラストラクチャを展開に使用し、段階的に実行したいと考えているため、IISの公開ストーリーが懸念されるはずです。 現在、このストーリーは非常に複雑で完全ではありません。

web.config変換が必要な別の例: https

最も参考になるコメント

最初の投稿に完全に同意します。 これは設計上かなり柔軟ですが、最終的には自動化が非常に難しいことが判明しました。 たとえば、別のサーバー上のIISに公開するアプリがあります。 また、ローカルIISで実行されます(フォルダーの公開を介して)。 そこで、web.configで開発環境を設定しました。 ただし、公開中に本番環境などに変更する必要があります。 私が推測するかなり一般的なタスク。 不可能だと思いますよね? リモートサーバーでweb.configを手動で編集する必要があります。

理想的には、環境の設定は「dotnetpublish」を介してサポートされている必要があります(すべての公開ターゲットに対して)。

dotnet publish ... -environment=Production

dotnet publishは、 web.%Enviroment%.config (Web.Production.config、Web.Development.config)ファイルを検索し、それをweb.configとマージ(変換)できます。 最後に、ASPNETCORE_ENVIRONMENTの正しい値が得られます。

    <environmentVariables>
        <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="value passed to publish" />
    </environmentVariables>         

全てのコメント91件

FWIW、同意します。 IIS設定用であることを明確にする必要があります。 もうweb.configは、テンプレートにデフォルトの

/ cc @sayedihashimi

これはIIS専用ですか? 問題の核心は、ASPNETCORE_ENVIRONMENT変数fullstopを使用して、Webサイトにどの環境にあるかを知らせることだと思います。

かなり一般的なシナリオは、さまざまなステージング/ QA環境が同じIISインスタンスの同じボックスでホストされることだと思います。 コードをテストするためにデプロイできる独自の「環境」を持つ3つのチームが存在する可能性がありますが(特定のブランチをデプロイするとします)、すべて同じボックスを使用しています。

appsettings.jsonが環境ごとにどのように切り替わるかを示すサンプルコードをいくつか取り上げると、次のようになります。

public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); }
上記のシナリオは、環境変数がシステム全体であるため、機能しません。 IIS、nginixなどがその前にある可能性があり、構成の交換は機能しません。

ほとんどの場合、上記が表示されたり、Dockerを使用したり、Puppet / Chefなどを使用してアプリの構成を管理したりして、アプリの設定がないようにする提案が出てきました。{env} .jsonですが、これで完全な状態からのパスになると思いますフレームワークMVCははるかに困難です。

@mindingdata Program.csどこから環境が発生するかを決定するロジックを実際に制御できます。 環境変数は、それを宣言する1つの方法にすぎません(主な方法)。 魔法のファイルや時刻に基づいて何か他のことをしたい場合は、 WebHostBuidler UseEnvironment(environmentName)に電話してください。

明確にするために、これは絶対にIIS構成専用です。 アプリ設定用の現在のJSON構成システムは非常に優れており、私はそれを完全にお勧めします。

さらに混乱させるために:web.configを使用してシステム環境設定をオーバーライドしようとすると、単に機能しないことがわかりました。 システム環境設定が「開発」に設定されていて、web.configを使用して「本番」に設定しようとすると(以下のように)、アプリケーションはまだ開発で実行されていると見なします。 (IISで実行されているASP.NET Coreアプリ)。

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

これは正しい場所だと思います。 N層のデ​​モを作成しましたが、データアクセス層プロジェクトにIHostingEnvironmentを挿入する方法がわからないようです。 そのプロジェクトは私がデータベースにアクセスする場所であり、そのレイヤーへの接続文字列を取得する唯一の方法は、構成ファイルのマジックストリングでOnConfigureメソッドをオーバーライドすることでした。

スローチーターも調べましたが、VSメソッドを使用しているか、環境変数を使用しているかに応じて、「デバッグ、リリース」または「開発、本番」の現在のメソッドを回避しているようです。

私が見逃している情報があるに違いありません。 MSは、誰もがシングルティアアプリを構築することを望んでいません。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
           var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json");

            var config = builder.Build();
            var connstr = config.GetConnectionString("connStr");            
            optionsBuilder.UseSqlServer(connstr);
        }

それで、これに関して何か進歩がありましたか?

魔法に頼ることなく、アプリの構成でenvを設定できるはずです

ええ、私もこれについていくらかの進歩を望んでいます。 現在、異なる環境変数を使用して、別々のプロジェクトを同じボックスに公開する方法がわかりません。

私はかなり単純な解決策を思いついた。 メインのappsettings.jsonファイルで、目的の環境を指定します。

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ActiveEnvironment": "Development"
}

次に、Program.CSで、IConfigurationを作成し、環境固有の構成ファイルをロードする前に、環境名を「ActiveEnvironment」の値に設定します。

public static void Main(string[] args)
{
    WebHost.CreateDefaultBuilder()
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        // Get the environment from our hostContext.
        var env = hostingContext.HostingEnvironment;
        config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

        // Build an initial configuration.
        IConfiguration Configuration = config.Build();

        // Set the environment name.
        env.EnvironmentName = Configuration.GetSection("ActiveEnvironment").Value;

        // Load the configuration file for our specific environment.
        config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true)
        .AddEnvironmentVariables();
    })
    .UseStartup<Startup>()
    .Build()
    .Run();
}

明らかに、異なる環境に公開する場合は、それに応じて「ActiveEnvironment」を変更する必要があります。

@DaleMckeown似たようなことをするつもり

@Swazimodoコンソールアプリケーションのコンテキストでこのソリューションを試したことがないので、

私たちはこれを別の方法で処理しました。 ビルドエージェントを設定します
環境固有の設定ファイルとルート設定ファイルを上書きします
それと。 私たちのビルドは、私たちが使用する環境ごとに個別のzipファイルを作成します
にデプロイします。

12:48の木、2017年10月26日には、デールMcKeownの[email protected]
書きました:

@Swazimodohttps ://github.com/swazimodo私はこのソリューションを試していません
コンソールアプリケーションのコンテキストであるため、よくわかりません。 最善の策
の環境変数を設定する別の方法があるかどうかを確認します
コンソールアプリケーション。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/aspnet/Home/issues/2019#issuecomment-339728441 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAx4bT20JSb0XSzNBIAiiubq9mTVKbW5ks5swLf6gaJpZM4NMx25

すべてのソリューションには、ビルド/公開後の何らかの調整が必要なようです。 結局、空のテキストファイルをアプリのルートにドロップし、それを環境として渡しました。 私は何かを逃しましたか?

最初の投稿に完全に同意します。 これは設計上かなり柔軟ですが、最終的には自動化が非常に難しいことが判明しました。 たとえば、別のサーバー上のIISに公開するアプリがあります。 また、ローカルIISで実行されます(フォルダーの公開を介して)。 そこで、web.configで開発環境を設定しました。 ただし、公開中に本番環境などに変更する必要があります。 私が推測するかなり一般的なタスク。 不可能だと思いますよね? リモートサーバーでweb.configを手動で編集する必要があります。

理想的には、環境の設定は「dotnetpublish」を介してサポートされている必要があります(すべての公開ターゲットに対して)。

dotnet publish ... -environment=Production

dotnet publishは、 web.%Enviroment%.config (Web.Production.config、Web.Development.config)ファイルを検索し、それをweb.configとマージ(変換)できます。 最後に、ASPNETCORE_ENVIRONMENTの正しい値が得られます。

    <environmentVariables>
        <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="value passed to publish" />
    </environmentVariables>         

@ evil-shrikeは、ビルド/公開時の構成変換についてhttps://github.com/nil4/dotnet-transform-xdtを参照して

おそらくユースケース。 アプリケーションランナーは。\ App_Dataの下のすべてに読み取り/書き込みアクセス権を持っていますが、。\の下の他のすべてを読み取ることしかできないため、ログを。\ App_Dataに書き込む必要があります。 私はWebデプロイを使用しており、App_Dataの下のlogsフォルダーを使用して次のようなweb.configをデプロイできるようにしたいと考えています。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath=".\<assembly>.exe" stdoutLogEnabled="true" stdoutLogFile=".\App_Data\logs\stdout" />
  </system.webServer>
</configuration>

これらの設定をweb.release.configではなくweb.configファイルに入れてみませんか? processPath=".\<executable>.exe"は、IIS Expressに対してローカルで開発しているときに、実行可能ファイルが存在する場所ではありません。 そのため、古き良き「HTTPエラー502.5-プロセス障害」エラーが発生します。

Jenkinsを使用してビルドを自動化し、NetFrameworkプロジェクトで環境ごとにvars構成を行う既存の方法は、web.config変換を使用します。 だから、ドットネットでもできると思いました。

msbuildは、web.config変換を行うためのaspnetコアcsprojとまだ互換性があることがわかりました!

TransformXml公開タスクをAsp.Net Corecsprojに追加できます。

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll" />

特定の変換ターゲットを追加します。

<Target Name="ConfigDev">
    <TransformXml Source="web.config" Transform="web.dev.config" Destination="web.config" /></Target>

たとえば、 web.dev.configASPNETCORE_ENVIRONMENT変数に対して、いくつかの変換を行います。

<system.webServer>
    <aspNetCore processPath="dotnet" arguments=".\Test.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" >
      <environmentVariables>
        <environmentVariable xdt:Locator="Match(name)" name="ASPNETCORE_ENVIRONMENT" value="dev" xdt:Transform="SetAttributes" />
      </environmentVariables>
    </aspNetCore>
</system.webServer>

公開を実行する前に、 msbuildを使用してweb.configを変換します。

msbuild Test.csproj /t:ConfigDev

「私はweb.configのファンではありませんが、AspNetCoreアプリをIISに公開した経験は本当に貧弱だと言って、これに接頭辞を付けさせてください。」

私はこのスレッドにこれ以上同意できませんでした。

通常のASP.Netでの構成変換が単純になった後、マシン全体のASPNETCORE_ENVIRONMENT変数へのこの依存関係全体が悪臭を

Microsoft自身の例でさえ、この行を追加するだけで、たとえば_appsettings.Production.json_ファイルを使用できると言っています...

            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

...しかし、選択した構成の名前には注意を払いません。 そのため、本番構成を選択した場合でも、appsettings.development.jsonを開こうとします。 いいえ、別の環境に公開するたびに、 ASPNETCORE_ENVIRONMENT変数を自分で手動で編集する必要はありません。 それはただ問題を求めているだけです。

_appsettings.XXXX.json_ファイルを使用する簡単で実用的な例はまだ見ていません。
ようやく完成するのが待ちきれません。 (はぁ...)

はい、これを修正してください!!

最初の本番ドットネットコアサイトをデプロイしたばかりですが、アプリを同じボックスに公開する方法がわからないため、同じサーバーにステージングインスタンスを簡単に配置できないという問題に直面しています。プロダクション設定。

今のところ@DaleMckeownソリューションを試してみるつもりです。うまくいくと思いますが、ソリューションというよりは回避策のように感じます。 環境変数は素晴らしいですが、サーバーと環境の比率が1対1である場合にのみ、企業の外部では、それが頻繁に発生することはないと思います。

@willapp私の提案は間違いなく回避策です。 しかし、それは機能します-私はしばらくの間、同じサーバー上で同じアプリの複数のバージョンを実行していて、問題はありませんでした。

公開する前に「ActiveEnvironment」設定を変更することを忘れないでください。問題はないはずです。

私はdkent600が述べたことに正確に直面しています:

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

本番サーバーでは機能しません。 アプリケーションは引き続き「appsettings.Development.json」値を使用します。これにより、公開時にxml変換の利点が最終的​​に無効になります。

DaleMckeownによって提案された回避策を試してみます。

ASPNETCORE_ENVIRONMENTを変更する唯一の合理的な方法は、web.configを使用することです。

あまり。 同じマシンで同じサイトの複数のインスタンスを実行する必要がある場合は、これがはるかに簡単な方法です

  • MyCoreSite

    • 置き場

    • ログ

  • env.Whatever

IISアプリをbinおよびprogram.csにポイントします

.UseEnvironment(ReadEnvExtensionFromParentFolder())

それでおしまい。 必要な数のサイトを作成し、変換を気にせずにbinにデプロイし、env.Whenverの名前を変更して環境を切り替えることもできます。

私はこれに賛成です。 テスト環境で機能しない本番サーバー用に構成されたURL書き換えがあります。 デプロイする適切なweb.configファイルを選択するための公開方法が見つかりません。手動でコピーする必要があります。

これについて何か進展はありますか? 最初のレポートから13か月が経ち、2.1.0がここにありますが、従来のIISホスティングではまだかなり貧弱です。 Azureを使用している場合は問題なく機能しますが、現在、私がホストしているサイトの大部分では、これを選択することはできません。

従来のIISホスティングの場合、コマンドライン(上記の@ evil-shrikeのように)で、また任意の.pubxml公開プロファイル内で目的の環境を設定することが有益であるように思われます。 @davidfowlが言ったように、これはweb.configとIISを使用して機能することを明確にする必要がありますが、それでもインストールベースのかなりの部分をカバーしていることは確かです。

現時点では、 Microsoft.DotNet.Xdt.Toolsweb.config変換を使用した非常に脆弱なソリューションがありますが、動作させるには環境ごとのビルド構成が必要であり、v2.1.0に更新した直後に壊れています。

この分野で計画があるかどうか、もしそうなら、それらは何であるかを聞くのは素晴らしいことです。 計画がない場合、または計画が遠い場合は、現在採用を余儀なくされている脆弱/半手動の方法よりも優れた暫定的な解決策が確かにありますか? 特にQAへの展開とステージングについては、VSのボタンを押すだけで、正しいことが起こっていることを知りたいと思っています。頭の知識や手動のプロセスに依存する必要はありません。

現在、計画はありませんが、 @ nil4によるこのツールhttps://github.com/nil4/xdt-samples/はかなり良さそうです。

@svallis試してみましたか?

人々が環境を設定したい主なものは何ですか?

@davidfowlええ、私の現在のソリューションはリンクしたツールを使用していますが、複数の宛先を公開するプロジェクトの場合、環境ごとにビルド構成が必要です。 csprojセットアップで何かをラッチするには、さまざまなビルド構成が必要です。私の目的では、通常、環境と1対1の関係になります。 例えば:

  • ビルド構成:デバッグ=環境:開発
  • ビルド構成:ステージング=環境:ステージング
  • ビルド構成:リリース=環境:本番

後者の2つについては、対応するweb.{Build configuration}.configappsettings.{Environment}.jsonがあり、 web.{Build configuration}.configは文字通りXDTであり、 web.configに最終的に適切なASPNETCORE_ENVIRONMENT環境変数。 したがって、たとえば、上記の例を続けると、 web.Release.configは次のようになります。

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

これは実際にはすべてコマンドラインからかなりうまく機能します。 dotnet publish -c Stagingなどを実行すると、正しい出力のフォルダーが生成され、必要に応じてweb.config変換されます。 しかし、それは単純化できるように感じます。 dotnet publish -iisenvironmentスイッチがあり、これが私たちのために行われ、それがVS公開で単純なテキストボックスとして公開された場合、ビルド構成、XDT、従来のIISホスティング状況では手動でなど。

ただし、VS内からは、現在問題があるようです。 現在、VS内からはまったく公開できません。また、v2.0.0で機能した場合でも、公開する前に正しいビルド構成を手動で選択する必要がありました。

@davidfowl私の観点からは、理想的には、Web配置を使用するときに、公開プロファイルの一部として環境を設定したいと思います。

第二に、公開のオプションが理想的です。 コマンドラインではなくVSIDEを介して公開することを好むため、

@willapp使用しているソリューションはcsprojツールを使用してセットアップされます。

最後に、 @ davidfowlによって上記で提案されたツールを試して

https://github.com/nil4/dotnet-transform-xdtの[プロジェクトレベルのツール]セクションの手順に従ってください(まだ2.1.0を使用していないため)。 デフォルトのWeb.configを自分で作成する必要がありました(デプロイ時にVSが生成するものからコピーしただけです)。次に、変換を使用してWeb.Debug.configを作成し、ASPNETCORE_ENVIRONMENTをDevelopmentに設定しました。プレスト! 変換された構成がデプロイされ、サイトが正しく起動するようになりました。

これに対するサポートが公式になればいいのですが、今のところこれは仕事をしています。

@davidfowl指定したリンクには、コマンドラインを使用して公開する必要があります。 VSGUIツールを使用して公開したいと思います。 開発者がプロ​​ジェクトを公開するためにCLIツールをインストールする必要がないようにします。 変換がサポートされていない場合、web.configでASPNETCORE_ENVIRONMENTを指定できる意味はありません。 この問題の賛成票の数を確認すると、バックログに移動する必要があります。

@ orobert91 VSは、コマンドラインツールをラップしたGUIです。 https://github.com/nil4/xdt-samples/を使用して、VS内からの公開中にweb.configを変換しています。 プロジェクト用に正しく構成すると、コマンドラインからもIDE内でも正しく変換されます。

@svallis確かに、ドキュメントを読み間違えました。 単純なコピータスクで問題を解決しました。

  <Target Name="CopyFiles" AfterTargets="Publish">  
      <Copy SourceFiles="web.$(Configuration).config" DestinationFiles="web.config" />  
  </Target>   

環境名の優等生を公開するmsbuildプロパティがあります-

$(EnvironmentName)

(https://github.com/aspnet/websdk/blob/d7d73e75918ec3168bd3e5d519d0decc04675faf/src/Publish/Microsoft.NET.Sdk.Publish.Targets/netstandard1.0/TransformTargets/Microsoft.NET.Sdk.Publish.TransformFiles.targets#L79 )。

現在、このプロパティが設定されている場合は、 appsettings.$(EnvironmentName).jsonを作成し、接続文字列情報をそのファイルに追加するだけです(要求された場合)。

今後、公開中にこのプロパティを設定すると、公開されたweb.configを更新して次のエントリを含めることもできます。

<environmentVariables>
      <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="$(EnvironmentName)" />
</environmentVariables>

これは、ここで説明したほとんどのシナリオで機能しますか?

environmentVariableの設定以外のシナリオでは、コアプロジェクトのweb.config変換( Xdt )の移植の実現可能性を検討します。

私は必要なシナリオをカバーしているように見える解決策を考え出しました-それが他の誰かに役立つ場合に備えて、ここに投稿したいと思いました。

私の場合、開発環境はローカルにあり、ステージング環境と本番環境の両方がリモートサーバー(同じサーバー)にあります。 IApplicationBuilderからアプリケーションのURLを取得し、それをswitchステートメントで使用して、 EnvironmentName値を設定することができました。

提供されている他のソリューションよりも「回避策」がはるかに少ないように見えますが、確かに好みに応じて決まります。

Startup.cs

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            env.DetectAndSet(app);

            ... other config method stuff here ...
        }

上記の方法は、 IApplicationBuilder内のプロパティコレクションに基づいてまとめた拡張機能です。 拡張メソッド(およびクラス)は次のようになります。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Hosting.Server.Features;
using System.Linq;

namespace MyRootNamespace.Common.Extensions
{
    public static class IHostingEnvironmentExtensions
    {
        /// <summary>
        /// Detects the current hosting url and sets the <see cref="IHostingEnvironment.EnvironmentName"/> accordingly.
        /// </summary>
        /// <param name="env">The <see cref="IHostingEnvironment"/> to set.</param>
        /// <param name="app">The <see cref="IApplicationBuilder"/> used to retrieve the current app url.</param>
        public static void DetectAndSet(this IHostingEnvironment env, IApplicationBuilder app)
        {
            var _appUrl = string.Empty;

            try
            {
                _appUrl = ((FeatureCollection)app.Properties["server.Features"]).Get<IServerAddressesFeature>()?.Addresses?.FirstOrDefault();
            }
            catch { }

            switch (_appUrl)
            {
                case "https://www.myurl.com":
                case "http://www.myurl.com":
                    env.EnvironmentName = EnvironmentName.Production;
                    break;
                case "https://staging.myurl.com":
                case "http://staging.myurl.com":
                    env.EnvironmentName = EnvironmentName.Staging;
                    break;
                default:
                    env.EnvironmentName = EnvironmentName.Development;
                    break;
            }
        }
    }
}

これが人々に役立つことを願っています( web.config変換が望ましくない場合)。

乾杯!

現時点では、これに関連する機能/修正は計画されていないため、この問題をディスカッションとしてマークしています。 それでも特定の機能のリクエストがある場合は、それらの問題を提出してください。優先されます。

このスレッドで見た回避策にはあまり満足していなかったので、別のアプローチを取りました。 私はこのスレッドに遭遇しましたStackOverflow: https

内部IISサーバーは運用チームによって管理されているため、組織内の開発者はこれらのサイトを作成しません。 運用チームは、PowerShellスクリプトを使用してこれらのサイトを作成します。 サイトのプロビジョニング時にApplicationHost.configにも関連する変更が加えられるように、そのスクリプトを変更するように依頼しました。 これで、そこにデプロイするだけで、.NETCore環境の管理について心配する必要はありません。 私たちの状況ではうまくいきました。

本当のDevOps環境では、とにかくAzureを使用していると思います。これにより、環境変数の設定が非常に簡単になります。

最新のSdkでは、msbuildプロパティ$(EnvironmentName)渡すだけで、ツールがASPNETCORE_ENVIRONMENTをこの値に設定します。

例:EnvironmentNameがstagingに設定されている場合、web.configには次のエントリがあります。

      <aspNetCore processPath="dotnet" arguments=".\WebApplication242.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
        <environmentVariables>
          <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
        </environmentVariables>
      </aspNetCore>

修正されたPR:
https://github.com/aspnet/websdk/pull/377

@vijayrkn有望なスタートのように見えます。 これにより、最終的にVS WebDeploy /公開プロファイルなどにサポートが組み込まれる予定ですか?

現在、この環境名を選択するためのUIはVSにありませんが、これがプロジェクトファイルまたはpubxmlに追加された場合、VSからの公開とコマンドラインの両方がそれを尊重します。

このためのUIサポートの追加も検討します。

@vijayrknこれは、 web.configファイルで公開するための唯一の解決策です-それは正しいですか?

@vijayrknええ、 pubxml形式のサポートを受けることは、これが私たちのユースケースに役立つ瞬間になるでしょう。 その時点で、すべてのXML変換のものを削除し、各pubxml適切な環境文字列を指定することができます。 UIのサポートは後日提供される可能性がありますが、それは単なるアイシングになります。

@ challamzinniagroup-いいえ、この機能にweb.configは必要ありません。
pubxmlファイルに以下を追加するだけで、残りは公開ツールが処理します。

<EnvironmentName>YourCustomEnvironment</EnvironmentName>

@ challamzinniagroup@ vijayrkn

web.configでのみ実行でき、環境間で変換する必要がある構成がない限り、それ以外の場合は、web.configをそのままにしておきます。 2行のコードで、どこからでも環境変数を読み取ることができます。 また、公開プロファイルや公開コードを微調整する必要はありません。一致するappsetting.XYZ.jsonのリストだけです。

@ThisNoName

これは、データベース接続文字列、サービスエンドポイント、クレデンシャル、またはdev-> staging-> productionから変更されるその他の多くのもののようなものを意味します。

同じ環境(クラウドの外部では非常に一般的)で複数のインスタンスを実行している場合は、web.config変換の柔軟性が絶対に必要です。 Microsoftがdotnetcoreでこの要件に対応しなかったのはかなりばかげています。彼らは、全員がAzureでホストしていて、インスタンスと環境の間に1対1の関係があると想定していました。

環境変数は実際にはクラウドの外に吸い込まれます。これは、アプリとは別の構成になってしまうため、デプロイメントの完全な停止を管理するのが難しくなるためです。

ここでの主な変更点は、これらのシークレットをソース管理に保存するのではなく、環境自体で構成する必要があることです。 Transformsは、公開時にデプロイメントターゲットを理解していることを前提としているため、良い慣習に直面しますが、常にそうであるとは限りません(特に、複数の環境がある場合)。 これらのN個のデプロイメントの1つの構成設定を変更するときに、本当に再デプロイする必要がありますか?

残念なことに、IISでは、環境変数を構成ファイルに設定して、アプリプールがそれらを認識できるようにする必要があります。 人々がターゲットマシン上でマシン全体の構成をセットアップすることを意図したことはないと思います(人々がそうするのを見たことがありますが)。

@willapp appsettings.jsonを使ってみませんか?

@willapp

M $には完璧なソリューションがありますが、ほとんどの人はweb.config変換の概念に固執しています。

複数のサイトを並べて配置する方法の1つを次に示します。 IISバイナリディレクトリの外部の任意の場所に環境値をスローし、program.csから読み取り/設定する必要があります。

  • IISRoot

    • MySiteDEV

    • 置き場



      • appsettings.json


      • appsettings.DEV.json


      • appsettings.PROD.json


      • web.config



    • ログ

    • env.DEV

    • MySitePROD

    • 置き場



      • appsettings.json


      • appsettings.DEV.json


      • appsettings.PROD.json


      • web.config



    • ログ

    • env.PROD

@davidfowl

ASP.NET CoreがIISでうまく機能しないのは残念だと人々に言っていますか? Microsoft .NET Core Architectとして?

ここでのパラダイムシフトは、コアがマルチプラットフォームであるものすべてに当てはまります。 IISは明らかにWindowsユーティリティであるため、多少の苦痛が予想されます。 このような場合の回避策は、物事が進むにつれて予想され、受け入れられる必要があります。 Windowsの機能をサポートするためにCoreで意図的な設計上の選択を行ったのは、直感に反するimoでした。

編集して追加:
これは、CoreがIISのすぐに使えるサポートをより適切にサポートする必要があるかどうかについての考えです。 それにもかかわらず、環境変数を使用することの議論は良い代替手段です...

@davidfowl

そして、これはまさにエンタープライズアーキテクチャとSMEの違いです。 私はFTSE100で働いており、展開をコードから分離することは理にかなっていますが、複数のサイトを独立して実行しているため、すべてのサイトをホストする単一のサーバーを使用する方が簡単で費用対効果が高くなります。 Web Deploy + Transformsの使用は、配信コードを変更するための実証済みのメカニズムであり、機能します。 場合によってはより良い代替手段がないと言っているわけではありませんが、Microsoftは、ほとんどのユーザーが.net Frameworkからコアに移行するときに慣れることを望んでいることを知って、変換のサポートを継続する必要があります。

私はこのスレッドの前半から解決策を持っているので、十分に満足しています。 私は彼らがこれを標準として含まないで少しボールを落としたと思います。

@willapp

変換は、ソースからコンパイルし、環境ごとに個別に公開するという考えに基づいていると思います。 代替案がはるかにエレガントなので、M $がそれを落としたのはうれしいです。

新しい設定では、リリース構成を使用してコードを1回だけ公開します。 実行中のすべてのインスタンスは、元のインスタンスの同一のバイナリコピーです。 デプロイメントは、次の環境DEV => TEST => Stageing => PRODへの単純なファイル同期である必要があります。

ASP.NET CoreがIISでうまく機能しないのは残念だと人々に言っていますか? Microsoft .NET Core Architectとして?

このように使用される環境変数は、マシンごとではなくプロセスごとに想定されているという事実を、人々はすぐには考えないと言っています。 歴史的に、Windowsでは、人々は環境変数をプロセスごとではなくマシン全体として識別し、それが混乱を引き起こしていました。 IIS 10では、アプリごとのプール環境変数を追加するためのサポートが追加されました。 ASP.NET Coreモジュールは、プロセスごとの環境変数の設定もサポートしています。

それでもこの機能はあります。 ここでの考え方には、ほとんど哲学的な変化があったと思います。 開発時にシークレットを指定しやすくするようなことはしたくありません。

@challamzinniagroup良い要約

これは、CoreがIISのすぐに使えるサポートをより適切にサポートする必要があるかどうかについての考えです。 それにもかかわらず、環境変数を使用することの議論は良い代替手段です...

右。 環境固有の情報を構成するためのワークフローは、引き続き特定の環境にある必要があります。 問題は、どうやってそこに到達するかです。 それは展開の一部ですか?

そうは言っても、2.2のツールでこれに対するサポートを追加していると思います。

cc: @vijayrkn

@davidfowl

「歴史的にWindowsで人々は環境変数をプロセスごとではなくマシン全体として識別する」と言うとき、コマンドラインSETのように、Windows環境変数を意味しますか?

.NETコアコンテキスト内の「環境」についての私の理解は、単なる変数であるためです。 デフォルトでは、systemまたはweb.configからASPNETCORE_ENVIRONMENTを読み取ります。 ただし、任意の規則により、任意のソースから上書きして取得できます。

そのアプローチに本質的に何か問題がありますか? Microsoft .NETチームの公式の立場がそれを行わない場合、私たちは真剣に再考する必要があるでしょう。 しかし、IISで.NET Coreを実行するように人々に指示することになりますが、残念ながら、これらのアプリを構成する簡単な方法はありません。 そうでないことを願っています。

ありがとう。

@ThisNoName

「歴史的にWindowsで人々は環境変数をプロセスごとではなくマシン全体として識別する」と言うとき、コマンドラインSETのように、Windows環境変数を意味しますか?

はい、これがまさにこのスレッドのすべてです。 (ここを参照)。 Davidが言うように、これらはプロセスごとに行うことができますが、私の経験では、dotnet coreのドキュメントのほとんどは、マシンレベルで設定することを前提としているため、複数のアプリインスタンスを同じサーバーに簡単にデプロイできないという問題があります。それらは同じ環境値を取得するため、dev / staging / prodを区別できません。

IIS10がアプリプールごとの設定をサポートしているという事実は素晴らしいです... Server2016が利用可能な場合。 私は2012年を実行しているので、これはオプションではありません。 繰り返しになりますが、私の問題は、Microsoftが物事をより良い方向に動かそうとしていることではありませんが、ASP.NETアプリケーションの展開で多くの人が当然と思っていたものに対する「レガシー」サポートを削除することは私にとって間違いのように感じます。 必ず新しいパターンを導入し、人々にそれらを採用するように促しますが、それを必要とする人がほとんどいないと確信するまで、レガシーの動作を削除しないでください。 そうでなければ、あなたがしているのは、dotnet coreを望んでいるが、移行パスがあまりにも苦痛だと思っている顧客のために障壁を設けることだけです。

@willapp

これは、デフォルトの設定です。 あなたはあなたが望む方法で環境を読んで設定することができます。 誰かがこのアプローチの重大な欠陥を指摘しない限り、少なくともそれは私の理解ですか?

   public class Program   {
        public static void Main(string[] args)   {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)   {
               return WebHost.CreateDefaultBuilder(args)
                .UseEnvironment(ReadEnvFromWherever())
                .UseStartup<Startup>()
        }

        private string ReadEnvFromWherever() { 
              // Get and return whatever by your own convention
              return "DEV";
        }
    }

@ThisNoName

重大な欠陥は、ソリューション構成に基づいて、VSTSからのWeb公開を使用して展開するときに、「ReadEnvFromWherever」メソッドが異なる値を返すようにするにはどうすればよいですか。 プリプロセッサディレクティブ(#if RELEASE ...)を使用できると思いますが、それはかなり汚い感じがします。

「旧世界」(ASP.NETフルフレームワーク)では、公開プロファイルを作成し、その一部として、構築するソリューション構成を選択します。 次に、その構成に基づいて構成変換を適用し、dev / staging / prodに公開しているかどうかに基づいて異なる構成を指定できるようにしました。

このワークフローは、単一のビルドパッケージを取得して各環境にプッシュする、最新のCIパイプラインには適合しないことを受け入れます。この場合、VSTSリリースパイプラインのようなものでデプロイ時に設定を挿入するか、プライムします。適切な環境変数を使用したサーバーインスタンス。この場合、パッケージをボックスにドロップするだけで、自動的に魔法のように機能します。 繰り返しになりますが、多くの中小企業やワンマンバンドはこの場所にいないと思います。そして、彼らが望む結果を生み出すVisualStudioから展開するプロセスを望んでいます。

これは、IISで実行され、従来提供されていたASP.NETホスティングである共有ホスティングプラットフォームに小さなプロジェクトを展開する場合にも重要です。 ホスティングコントロールパネルを介してウェブサイトごとに環境変数を設定する機能がないため、現実的なアプローチは、変換とweb.configを使用することだけです。

ただし、次のリリースでは、これはすべて適切なソリューションになると思われます。また、VSサポートが組み込まれているため、少し先に進む予定です。 うまくいけば、ホスティングプロバイダーとレガシーシステムがアップグレードまたは改善されるまで、この機能に依存する既存のワークフローを持つ人々をサポートするでしょう。

@willapp

慣例により。 以前に投稿した例を見ると、親フォルダーからenv.DEVを読み取り、環境変数としてファイル拡張子を使用できます。 ただし、アプリのルートにMySiteDEV、MySitePRODなどの名前を付け、フォルダー名を解析して環境名を取得するなど、任意の規則に従うことができます。

コードが環境によって異なる場合は、IHostingEnvironment.EnvironmentNameから環境値を読み取ることができます。

これは、システム変数またはweb.configからASPNETCORE_ENVIRONMENTを読み取る.NETCoreと違いはありません。

@ThisNoName

しかし、手動でコピーする以外に、どのようにして_env.DEV_を親フォルダーに入れるのでしょうか。 あなたが言おうとしていることはわかりますが、ここでのポイントを見逃していると思います。以前は、すぐに機能するソリューションがありました。 これは、ツールのサポートがdotnetcoreの展開プロセスの一部と見なされていなかったためではありません。

私はそれが削除された_理由_を取得します(適切なCIプロセスがある場合はより良い代替手段があるため)が、多くの移行ユーザーがまだそれを望んでいるときはかなり近視眼的だったと思います。

@willapp

初期設定中に一度コピーすると、それ以降のすべてのデプロイメントはbinフォルダーに移動します。 再コンパイル、公開、変換はありません。 それが本来あるべき姿であり、余分な3行のコードが必要です。 M $です。 3か月前までは、.NETCoreでActiveDirectoryを呼び出すことさえできませんでした。

@ThisNoNameこのM $のもので真剣に受け止められることを期待していますか。 2018年だと気づいていますよね?

あなたの提案は、共有ホスティングプラットフォームへのWebデプロイのコンテキストでは意味がありません。 何に賛成か反対かはわかりませんが、ASP.NET Coreの次のリリースに機能が追加され、公開プロファイルで環境変数を指定できるようになります。変換などは必要ありません。 また、フォルダ名を使用した非標準的なアプローチも必要ありません。フォルダ名は、管理できる場合とできない場合があります。

@ willapp 、@ svallis
私がもう少し上に投稿した解決策は、場合によっては機能します。 URLをプルして、それに基づいて環境を設定できます。 どのホスティング環境でも、URLを完全に制御できます。 これはまだ「ハック」であり、回避策であることに気づきましたが、通常はほとんどの場合機能するはずです。 私のホスティング会社の場合、私が受け取っていたURLはlocalhost:portベース( "127.0.0.1:7777")だったので、私にとっては理想的ではないことがわかりました。 ただし、サブドメインとして設定しているため、さまざまな環境でルートフォルダーのパスを設定することもできます。ルートアプリのパスを取得するのも非常に簡単です。

        public static string DetectAndSet(this IHostingEnvironment env, ILogger logger)
        {
            switch (env.ContentRootPath)
            {
                case "h:\\root\\home\\www\\api":
                    env.EnvironmentName = EnvironmentName.Production;
                    break;
                case "h:\\root\\home\\www\\api-staging":
                    env.EnvironmentName = EnvironmentName.Staging;
                    break;
                default:
                    env.EnvironmentName = EnvironmentName.Development;
                    break;
            }

            logger.LogInformation($"Application root path discovered as '{env.ContentRootPath}'. Environment set to '{env.EnvironmentName}'");

            return env.EnvironmentName;
        }

環境をコード内で決定するか、デプロイ時に決定するか、事前に環境内で直接事前に決定するかを選択することは、私が取り組んでいる議論ではありません。これらの中小企業に合理的な修正を提供しているだけです。ホスティング制御が制限されており、修正が必要な個人。 私の場合、これはコードワンスアンドフォーゲットです-まさに私が必要としているものです。

さらに下流では、以下を含めるだけで、変換を必要とせずにappsettings.jsonファイルから構成値を簡単に取得できます。

"{configName}.{environmentName}": "{value}"

設定ファイルにあり、構成ごとに3つのエントリがあります(環境ごとに1つ)。 このファイルには非常に少数の構成しか含まれていないため、重複は大した問題ではありません。

お役に立てれば!

@challamzinniagroup慣例により、相対フォルダーのパスと名前を使用する方が簡単です。

@svallis全体のコンセプトは、一度公開してバイナリレベルでデプロイすることです。 したがって、公開プロファイルごとに変数を設定できたとしても、それは方法ではありません。

@ThisNoNameあなたにとって、おそらくそれは簡単です-しかし、他の人のためにそのようなことを想定しないでください。 私の場合、公開/コピーの前に宛先ディレクトリをクリアするための設定があります。そのため、ソリューションでは、毎回、各環境ファイルを手動で再アップロードする必要があります。 それは間違いなく簡単ではありません。

@challamzinniagroup同意します。 すべての状況は異なります。 結論として、環境は単なる変数であり、Microsoftが次善の策を提供するのを待つのではなく、適切と思われる方法で環境を制御できます。 そして、それらが出てくるものは何でも、とにかく別のコンベンションベースのソリューションです-システムまたはweb.configからいくつかの値を読み取り、環境を設定します。

ところで、あなたはまだ慣習を使うことができます。 appsettingsが単一のミドルワードを使用する必要があることは言うまでもなく、ステージング/プロダクションには特別な意味はありません。 このようなことを簡単に実行して、一致するフォルダー名を渡すことができます。

appsettings.api.json
appsettings.api-staging.json

コンベンションベースのソリューションを使用すると、再コンパイルや再公開することなく、新しいインスタンスを起動できます。

@vijayrknpubxmlの使用について詳しく教えてください。
SDKを2.1.302(x64)にアップグレードして、pubxmlを変更しましたが、公開されたweb.configで違いがわかりません。

@ wggley-修正は2.1.302では利用できません。 次のリリースで利用可能になるはずです。

ここから修正を含むcliのプレビューバージョンを試すことができます-https ://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x64.exe

上記のプレビューバージョンで問題が発生した場合はお知らせください。

ありがとう@vijayrkn次のリリースを待って、新しい公開で使用してみます。
@frankhoffyソリューションが魅力のように私のために働いたことを指摘したいと
https://stackoverflow.com/questions/31049152/publish-to-iis-setting-environment-variable/36836533#36836533
最初の回答(最も投票された回答)を探します。

公開中のWeb構成変換のサポートが2.2プレビュー1で利用可能になりましたhttps://www.microsoft.com/net/download/dotnet-core/2.2

@vijayrknどこかに基本的なサンプルがありますか? ASPNETCORE_ENVIRONMENTを設定する基本的な変換を使用して、同等のhelloworldをユーザーに示すのは素晴らしいことです。

ASPNETCORE_ENVIRONMENTを設定するには、ユーザーはmsbuildプロパティ '$(EnvironmentName)'を設定できます。 web.configトランスフォームを使用して他の環境変数を設定する方法を示すサンプルを追加します。

これがサンプルリポジトリです-https ://github.com/vijayrkn/webconfigtransform

Readmeには、これがどのように機能するかについての詳細があります。
https://github.com/vijayrkn/webconfigtransform/blob/master/README.md

お役に立てれば!

@ Eilon-この問題を解決できます。 これは修正され、最新のプレビューで利用できます。

@vijayrkn [公開設定]ダイアログから環境を設定するように公開設定を構成する方法が明確ではありませんか? 両方のサイトが同じサーバーにデプロイされている場合、ステージングサイトと本番サイトを区別するために、このダイアログで実際に何を変更できますか?

.NET Coreのこの側面は、非常に厄介なようです。 フォルダごとに環境を指定する方がはるかに簡単である必要があります。 サーバー全体の環境変数は、私たちの状況ではまったく機能しません。 誰もが本番サイトとは異なるサーバーでステージングサイトを実行できるわけではありません。

設定はアプリケーションごとです。

申し訳ありませんが、それは私の質問に本当に答えません。 おそらく私は何かを誤解しています。

ここにいくつかの擬似ドキュメントありますhttps://github.com/vijayrkn/webconfigtransform/blob/master/README.mdは(私たちは本当のドキュメントにこれを取得する必要があり@vijayrkn)。

@vijayrkn公開ダイアログでこれをどの程度サポートしていますか?

現在、公開ダイアログは公開環境の設定をサポートしていませんが、環境は公開プロファイルで手動で設定するか、特定の変換を適用できます。

@ nmg196 -web.configで「ASPNETCORE_ENVIRONMENT」を設定するだけの場合は、publishprofileにenvironmentnameを追加するだけです。

例:
https://github.com/vijayrkn/webconfigtransform/blob/master/Properties/PublishProfiles/FolderProfile.pubxml#L18

高度なシナリオ(ASPNETCORE_ENVIRONMENT環境変数の設定以外)の場合、上記のドキュメントに記載されているように、web.config変換を適用できます。

@ davidfowl -Angelosには、web.config変換サポートを文書化するためのアイテムがあります。

@vijayrknTFSのCI / CDでの使用方法は? TFSでp:CustomTransformFileNameを使用してdotnetpublishを使用できませんでした

このmsbuildプロパティをdotnetpublishに渡すことができます。

ここでこのサンプルを参照できます-https://github.com/vijayrkn/webconfigtransform/blob/master/publish.cmd

これにより、CustomTransformFileNameプロパティがdotnetpublishに渡されます

dotnet publish /p:Configuration=Release /p:EnvironmentName=Staging /p:CustomTransformFileName=custom.transform

@vijayrkn
ドキュメントを読みましたが、web.configを変換できません。 基本的に、readme.mdにあるすべてのコマンドを試しましたが、いずれも変換が実行されません。

ただし、Microsoft.Web.XmlTransform.dllを使用して、公開操作とは別に変換を実行するPowerShellスクリプトを作成することができました。

私の質問は、msbuildとdotnetのどのバージョンを使用していますか?
私は使っている:
dotnet --version 2.1.104
dotnet msbuild -version 15.6.84.34536

ありがとう

@ stephenarsenault1
機能を点灯させるには、ここからビルドのいずれかをインストールする必要があります-https://www.microsoft.com/net/download/dotnet-core/2.2

最新-https://www.microsoft.com/net/download/thank-you/dotnet-sdk-2.2.100-preview3-windows-x64-installer

@davidfowlは書いた:

ここにいくつかの擬似ドキュメントありますhttps://github.com/vijayrkn/webconfigtransform/blob/master/README.mdは(私たちは本当のドキュメントにこれを取得する必要があり@vijayrkn)。

@vijayrkn公開ダイアログでこれをどの程度サポートしていますか?

これが実際のドキュメントに追加されたかどうか知っていますか?追加された場合は、リンクを教えてください。

公開プロファイルで<EnvironmentName>を使用するようになりました。 ただし、この上にUIを配置して、見やすくすることをお勧めします。 これは後日来ると思いますか?

dotnetpublishでデフォルトでweb.config変換を有効にするのは重大な変更だと思います。 .NET Core SDK 2.2.101をインストールした後、CI / CDシナリオが壊れました。 私たちのパイプラインは、リリースごとに1回だけdotnet publishを使用して公開されたアーティファクトを作成するように構成され(ビルドワンスルール)、変換は実際のデプロイに自動的に適用されます(Octopusによって実行されます)。 この変更に関するドキュメントには何の言及も見つかりませんでした。 デプロイ後にweb.configの構成ブロックが2倍になった理由を理解するために少し時間を費やしました。 どうやら、変換は2回適用されました: dotnet publishとリリース管理ツールによるものです。

<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>設定でweb.config変換を無効にした後、TransformWebConfigもスキップし(TransformXmlとともに)、公開プロセス中に%LAUNCHER_PATH% %LAUNCHER_ARGS%変数と

これは、App.Configファイルを使用するコンソールアプリで機能しますか?

例を見ることができますか?

@dmitryshunkov $(RunXdt)をfalseに設定すると、カスタムXmlトランスフォームの実行をスキップできます。

@ auserx -SDKスタイルのプロジェクトであれば、機能するはずです。

このページは役に立ちましたか?
0 / 5 - 0 評価