ASP.NET5 クロスプラットフォームでアプリケーションの動作環境を構築する
実際に存在している、ASP.NET5アプリケーションを、Windows10 + Visual Studio 2015, Mac そしてUbuntuで動作させたので、そのTipsを記録しておきたい。今回のアプリケーションは、.NET Core 1.0.0-beta5を用いている。最新バージョンでないところが実際に現場で遭遇する状態に近いかもしれないので、その方法を共有したい。
対象のアプリケーションは、Microsoftが公開しているPartsUnlimitedというアプリケーションである。Microsoft / PartsUnlimitedこのリポジトリのdev/beta5ブランチで実施してみたい。
ASP .NET5の情報はまだそんなに多くない。ASP.NET Get Startedが英語リソースだがおすすめだ。
Windows10 + Visual Studio 2015
Installing ASP.NET 5 On Windows
Visual Studio 2015をインストールします。このアプリのGet Startedを読むと、Visual Studio 2015 RC対応です。ところが、すでにダウンロードできない。また、Microsoft SDK for .NET (VS 2015) - 2.6なので、これもRC用だ。
この場面では、Visual Studio 2015をダウンロードして、それに対応した、Microsoft SDK for .NET (VS 2015) - 2.7をダウンロードすればよい。
また、ASP.NET5関係の用語がよくわからない人はこの記事が秀逸。「最新.NET技術がよく分からない」と感じる人のための用語整理
1. monoのランタイムを取得し.NET Coreのバージョンを変える
コマンドプロンプトをつかって、このdnvmコマンドをつかって、ランタイムを取得します。
# dnvm install 1.0.0-beta5
# dnvm list
Active Version Runtime Arch OperatingSystem Alias
------ ------- ------- ---- --------------- -----
1.0.0-beta5 mono linux/darwin
# dnvm use 1.0.0-beta5
2. プロジェクトのチェックアウトと選択
その後、githubから、プロジェクトをTeam Explorerで複製して、分岐で、dev/beta5を指定して、ソリューションPartsUnlimited.slnを選択します。
3. プロジェクトのビルド
その後、プロジェクトを右クリック > プロパティ > アプリケーションのページのSolution DNX SDK version を 1.0.0-beta5に変更して、リビルドしておきます。エラーがでなければ問題ありません。その後、デバッグ実行をして、http://localhost:5001を選択するとページを見ることができます。
Mac
Macへのインストールも非常に簡単にできます。HomeBrewをつかって簡単にインストールできます。
Installing ASP.NET 5 On MacOS X
1. monoのインストール
わたしの環境だと、nodejs, npm, gruntなどはインストール済みであった。皆様もホームページの手順通りでインストール可能なので、インストールされたい。
$ brew install mono
$ curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | sh && source ~/.dnx/dnvm/dnvm.sh
$ dnvm list
$ dnvm install 1.0.0-beta5
$ dnvm use 1.0.0-beta5
これは、手順ではありませんが、このリポジトリは現時点ではバグがあります。(25th Aug)下記のproject.jsonのカッコが一個おおいので、取り除いておきます。
vim /Users/ushio/Codes/devopshackathon/PartsUnlimited/src/PartsUnlimited.WebJobs.UpdateProductInventory/project.json
2. プロジェクトのビルド
プロジェクトのビルドは次のコマンドです。
$ dnu restore
3. Webサーバーの実行
次のとおり、kestrelサーバーを実行
$ cd PartsUnlimitedWebsite
$ dnx . kestrel
ブラウザで次のURLを開けるといい。
http://localhost:5001
Ubuntu
Ubuntuは、手順にある通りではうまくいきません。実際に手順通り実施しても、NuGetのライブラリの取得がキャンセルされ、NuGetのライブラリが取得できない状況が発生します。そして、この現象は複数の理由で発生しますが、エラーメッセージだけではわかりませんので、発生原因をまとめて整理しています。
1. インストール手順の全体像
Ubuntuの手順はややこしいので、Vagrantで、アプリの実行まで出来るスクリプトを作成してみましたので、GitHubで共有しておきます。TsuyoshiUshio / AspNetDevBeta05
複数のファイルがあるが、Vagrantfileから各シェルファイルが実行される。最初に実行されるのは、parts_unlimited.sh経由で、common_ubuntu.shが実行される。これは、ubuntuの一般的な設定なので気にしなくても良い。
2. Vagrantならではのポイント
まず、VagrantでUbuntuを立ててそこに、このアプリの場合、ある程度メモリがある方が良さそうだ。Vagrantファイルで指定しておく
master.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
また、普通にシェルを書くと、rootでシェルが実行されるので、次のオプションをつけて、シェルがvagrantユーザで実行されるようにしておく
master.vm.provision "shell", path: "parts_unlimited.sh", privileged: false
これで、準備は完了です。
3. ASP.NET 5関連のインストール
実体はcommon_asp_dotnet5.shに記述しています。
最初の方の手順は、先に示した公式のインストール手順のままです。
このアプリの場合は、.NET Core 1.0.0-beta5を使うように設定をします。
dnvm install 1.0.0-beta5
dnvm use 1.0.0-beta5
次のポイントは次のパートです。これを全部入れておかないと、NuGetの取得でエラーになります。
次のようなエラーになります。こうなる原因は様々なので、次に対策をかいておきます。
==> master_01: Warning: DownloadPackageAsync: https://www.nuget.org/api/v2/package/Microsoft.AspNet.FileProviders.Abstractions/1.0.0-beta5
==> master_01: A task was canceled.
==> master_01: GET https://www.nuget.org/api/v2/package/Microsoft.AspNet.FileProviders.Abstractions/1.0.0-beta5
==> master_01: Warning: DownloadPackageAsync: https://www.nuget.org/api/v2/package/Microsoft.AspNet.Hosting.Abstractions/1.0.0-beta5
==> master_01: A task was canceled.
==> master_01: GET https://www.nuget.org/api/v2/package/Microsoft.AspNet.Hosting.Abstractions/1.0.0-beta5
==> master_01: Error: FindPackagesById: System.Diagnostics.Debug
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Globalization
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Diagnostics.Tools
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Linq.Expressions
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Linq
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Reflection
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Linq.Queryable
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Runtime
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Resources.ResourceManager
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Security.Claims
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Runtime.Extensions
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Text.Encoding
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Security.Principal
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.AspNet.Authorization
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: System.Threading.Tasks
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.AspNet.Mvc.ApiExplorer
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.AspNet.Cors
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.Framework.Caching.Memory
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.AspNet.Mvc.Razor
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.Framework.DependencyInjection
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.AspNet.Http.Extensions
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.AspNet.FileProviders.Abstractions
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.AspNet.Hosting.Abstractions
==> master_01: A task was canceled.
==> master_01: Error: FindPackagesById: Microsoft.Framework.Logging.Abstractions
==> master_01: A task was canceled.
==> master_01: ----------
==> master_01: System.Threading.Tasks.TaskCanceledException: A task was canceled.
対策その1 ルート証明書
Installing on Linux - missing certificate import steps #184
原因の一つ目は、このアプリが使っているライブラリのCAルート証明書がないことに起因しています。本来は取得しないといけませんが、ca-certificates-monoというライブラリがいつの間にかできていますので、これを使うようにしましょう。
ちなみに、これらの手順はどう考えたかというと、DockerHubのMonoのDockerfileを参考にしている。
sudo apt-get update
sudo apt-get install -y mono-devel ca-certificates-mono fsharp mono-vbnc nuget \
&& sudo rm -rf /var/lib/apt/lists/*
そのあとは、普通にnodejs, npm, gruntをインストールしています。
対策その2 NuGet.Configの設定
これは公式にもある手順ですが、Configuring the feed used by dnu to restore packagesこのページにあるように、~/.config/NuGet/NuGet.configを書いておかないといけません。このアプリではdevelop中のライブラリを参照しています。
このparts_unlimited.shは下記のようなNuGet.Configを、~/.config/NuGet/NuGet.Configに、保存しています。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="AspNetVNext" value="https://www.myget.org/F/aspnetvnext/api/v2/" />
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
</packageSources>
<disabledPackageSources />
</configuration>
対策その3 Monoのスレッドプールの設定
Monoのスレッドプールの設定をしない場合はこうなることがあるようです。わたしの場合は、Winマシンでは発生しませんでしたが、家のMacで同じくVagrantを使ったら発生しました。まったく同じコードなのに動かなかったので相当混乱しました。
MONO_THREADS_PER_CPU
を2000に設定します。他の設定値も下記のスレにのっています。
parts_unlimited.shにも同様にコードをしています。
export MONO_THREADS_PER_CPU=2000
Package restore on mono super slow and tons of requests end up being cancelled #1590
アプリケーションの起動
基本的に、GitHubから、dev/beta5のブランチを取得し、Macの時と同じくの箇所で問題のあるファイルを修正しています。
#bad know-how for this repository. Until it will fix this.
mv /tmp/user-shell/inventory_project.json ~/PartsUnlimited/src/PartsUnlimited.WebJobs.UpdateProductInventory/project.json
ここまでくると、最後は同じです。
dnvm use 1.0.0-beta5
dnu restore
cd src/PartsUnlimitedWebsite
dnx . kestrel
実際にこのアプリケーションを動作させたい場合、VirtualBoxとvagrantをインストールしたのち
$ vagrant up
で、Ubuntu上に、各種設定を入れた上で、PartsUnlimitedアプリケーションが起動されます。
お疲れ様でした!