Linux を使って ASP .NET Core を使ってみようとしてハマった事のメモです。
やりたかった事
フロントエンドで接続を受け付けて、AP サーバーを呼び出す平凡な構成を考えてみます。インターネットからの接続を Nginx をリバースプロキシにして ASP .NET Core の Kastrel を呼び出します。
この辺のドキュメントを参考に環境構築して、Windows で作った実行ファイルを Linux にコピーして実行してみました。
プロジェクトの作成
mkdir ShinjiLocation cd ShinjiLocation dotnet new webapi
実行ファイルの作成
dotnet publish -C Release
その 1) Windows と Linux のバージョンをあわせる
Windows 作った空のプロジェクトを Linux で実行しようとしたところ、エラーが出てしまいました。
[root@ap01 ShinjiLocation]# dotnet ShinjiLocation.dll Error: An assembly specified in the application dependencies manifest (ShinjiLocation.deps.json) was not found: package: 'Microsoft.AspNetCore.Antiforgery', version: '2.0.1' path: 'lib/netstandard2.0/Microsoft.AspNetCore.Antiforgery.dll'
Windows で作ったプロジェクトと Linux で作ったプロジェクトを比較すると、.csproj で指定されているライブラリのバージョンが違っていました。
Windows で作ったプロジェクト
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.0</TargetFramework> </PropertyGroup> <ItemGroup> <Folder Include="wwwroot\" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" /> </ItemGroup> </Project>
Linux で作ったプロジェクト
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.0</TargetFramework> </PropertyGroup> <ItemGroup> <Folder Include="wwwroot\" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> </ItemGroup> </Project>
今回は、Windows で作ったプロジェクトの Microsoft.AspNetCore.All と Microsoft.VisualStudio.Web.CodeGeneration.Tools のバージョンを Linux で作ったプロジェクトにあわせることで回避しました。
この件について、後日 id:shibayan に聞いたところ、親切に .NET Downloads を見るように教えてくれました。
確かに yum コマンドで確認すると、複数のバージョンが登録されています。
インストールするとき、ドキュメントのサンプルそのままに古いバージョン (2.0.0) を指定してしまっていたのが原因でした。インストール前にはちゃんと最新バージョンをチェックしないといけないですね。
その 2) localhost 以外から Kastrel に接続できるようにする
Linux サーバーで Web API が実行できるようになったので、リバースプロキシ経由でアクセスしてみようとしたのですが、別のサーバーから接続することができませんでした。
設定項目らしきものも見当たらず、手詰まりになりそうだったので、アメリカに出張中の id:okazuki に助けを求めたところ、T ボーンステーキの画像と一緒に、以下の URL が送られてきました。
どうやら、Program.cs にある BuildWebHost 関数の中で Kestrel に関するパラメーターを指定できるようです。
早速、UseKestrel に Listen オプションだけを指定して UseStartup と Build の間に追加したところ、無事に別ホストのリバースプロキシ経由でアクセスできるようになりました。
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseKestrel(options => { options.Listen(IPAddress.Any, 5000); }) .Build(); } }
とまぁ、こんな感じでようやく実行環境ができました。(Azure 使ってたらこんな事するまでもなかったんだとは思いますが...) あとは中身を作っていくだけですね!