kazuakix の日記

Windows Phone とか好きです

ASP .NET Core で作った Web API を Linux サーバーでホストしてみる

 Linux を使って ASP .NET Core を使ってみようとしてハマった事のメモです。

やりたかった事

 フロントエンドで接続を受け付けて、AP サーバーを呼び出す平凡な構成を考えてみます。インターネットからの接続を Nginx をリバースプロキシにして ASP .NET Core の Kastrel を呼び出します。

f:id:kazuakix:20180203160341p:plain

 この辺のドキュメントを参考に環境構築して、Windows で作った実行ファイルを Linux にコピーして実行してみました。
 
プロジェクトの作成

mkdir ShinjiLocation
cd ShinjiLocation
dotnet new webapi

f:id:kazuakix:20180203171748p:plain
 
実行ファイルの作成

dotnet publish -C Release

f:id:kazuakix:20180203170801p:plain
 

その 1) Windows と Linux のバージョンをあわせる

 Windows 作った空のプロジェクトを Linux で実行しようとしたところ、エラーが出てしまいました。

f:id:kazuakix:20180203171914p:plain

[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 を見るように教えてくれました。

f:id:kazuakix:20180205214626p:plain

 確かに yum コマンドで確認すると、複数のバージョンが登録されています。

f:id:kazuakix:20180205215811p:plain

 インストールするとき、ドキュメントのサンプルそのままに古いバージョン (2.0.0) を指定してしまっていたのが原因でした。インストール前にはちゃんと最新バージョンをチェックしないといけないですね。
  

その 2) localhost 以外から Kastrel に接続できるようにする

 Linux サーバーで Web API が実行できるようになったので、リバースプロキシ経由でアクセスしてみようとしたのですが、別のサーバーから接続することができませんでした。

 設定項目らしきものも見当たらず、手詰まりになりそうだったので、アメリカに出張中の id:okazuki に助けを求めたところ、T ボーンステーキの画像と一緒に、以下の URL が送られてきました。

f:id:kazuakix:20180203164729p:plain

 どうやら、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 使ってたらこんな事するまでもなかったんだとは思いますが...) あとは中身を作っていくだけですね!