Posted at

.NET Core とDockerで C#なウェブアプリケーションをLinuxで開発する

More than 1 year has passed since last update.


動機

正直Windows系の開発に興味がないのでC#, .NETにも興味は無いのですが、.NET Coreの登場によってLinux上で動くBetter JavaとしてのC#にはポテンシャルを感じます。

Microsoftも肩入れしているDocker上で動かすことができ、Amazon ECS上で運用できる可能性を考えると良い選択肢だと思われるのでここはひとつ冬休みの自由研究として学んでみたいと思います。

https://docs.microsoft.com/ja-jp/dotnet/articles/core/docker/building-net-docker-images

ここに書かれていることがほぼ全てですが、2016/12/27現在現在若干ハマりどころがあるので書いておきます。

また、各ステップごとで何が変更されるのかを下記のリポジトリに公開してあるので参考にしてください。

https://github.com/NewGyu/dotnet-core


環境の準備

筆者の環境は Linux newgyu-XPS-13-9350 4.4.0-47-generic #68-Ubuntu SMP Wed Oct 26 19:39:52 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux です。要するにUbuntu16.04です。

会社のMacでも試していますが、だいたい同じです。(きっと)


yeoman をセットアップする

ゼロからプロジェクト構成を作っても良いのですが、MSのドキュメント通りyeomanのジェネレーターを使うのが手っ取り早いです。(ということでNode.jsの4以降が必要です)

$ npm install -g yo generator-aspnet generator-docker


dotnetコマンドラインツールをセットアップする

公式チュートリアルではDockerを使っているので、ローカルに.NET Coreは要らんのかと思ったらそうでもなく、あとからVisual Studio Codeと連携させるために必要になります。

https://www.microsoft.com/net/download/core#/current

ここからインストールしましょう。

注意すべきはバージョン1.1にする必要があるということです。

というのも後述のジェネレーターでは1.1に依存したコードが吐かれるためです。


Visual Studio CodeにC#機能拡張を入れる

https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp


プロジェクトを作る


aspnetジェネレーターで雛形を生成する

yeomanをインストールしたらベースのプロジェクトを生成します。

$ yo aspnet


_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
|--(o)--| │ marvellous ASP.NET Core │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `

? What type of application do you want to create? Web Application
? Which UI framework would you like to use? Bootstrap (3.3.6)
? What's the name of your ASP.NET application? WebApplication
:
Your project is now created, you can use the following commands to get going
cd "WebApplication"
dotnet restore
dotnet build (optional, build will also happen when it's run)
dotnet ef database update (to create the SQLite database for the project)
dotnet run

いろいろなテンプレートがあるのですが、ログイン機能などを有するWebApplicationを選びました。

生成されるコードはこちらになります。

https://github.com/NewGyu/dotnet-core/commit/03cd32a0d2dbc3cee4b997542c55195e6bd1dd0e


dockerジェネレーターを使う

aspnetジェネレーターの時点で、


  • 自身のローカルで動かせる

  • Dockeで動かせる

という状態になっていますが、dockerジェネレーターによって、


  • Visual Studio Code でデバッグできるようになる

  • リリースビルドとデバッグビルドを使い分けられるようになる

という設定が追加されます。

$ yo docker


_-----_ ╭──────────────────────────╮
| | │ Welcome to the Docker │
|--(o)--| │ generator! │
`---------´ │ Let's add Docker │
( _´U`_ ) │ container magic to your │
/___A___\ /│ app! │
| ~ | ╰──────────────────────────╯
__'.___.'__
´ ` |° ´ Y `

? What language is your project using? .NET Core
? Which version of .NET Core is your project using? rtm
? Does your project use a web server? Yes
? Which port is your app listening to? 5000
? What do you want to name your image? dotnet-core
? What do you want to name your service? dotnet-core
? What do you want to name your compose project? dotnetcore
? Overwrite .vscode/launch.json? overwrite
force .vscode/launch.json
conflict Dockerfile.debug
? Overwrite Dockerfile.debug? overwrite
force Dockerfile.debug
conflict Dockerfile
? Overwrite Dockerfile? overwrite
force Dockerfile
identical docker-compose.debug.yml
identical docker-compose.yml
identical dockerTask.ps1
identical dockerTask.sh
? Overwrite .vscode/tasks.json? overwrite
force .vscode/tasks.json
We noticed your project.json file didn't use portable .pdb files. We've fixed that for you.
Your project is now ready to run in a Docker container!
Run dockerTask.sh to build a Docker image and run your app in a container.

生成されるコードはこちらになります。

https://github.com/NewGyu/dotnet-core/commit/2c3877d89cbef7032a88a08f77451bf1644495d4


Nugetリポジトリから依存ライブラリを取得

$ dotonet restore


dockerジェネレータがいろいろ残念なので補正する

ここで、Visual Studio CodeでF5を押せばデバッグ実行…といきたいところですが、dockerジェネレータが吐くコードに現状に即していない箇所があるため修正を余儀なくされます。


Dockerファイルの指すイメージのバージョン

https://github.com/NewGyu/dotnet-core/commit/945f75637e1254907d7355cdead531f5d20c635c

残念なことに、1.0系イメージを指しているので補正します。


Dockerfile.debugのデバッガインストールの補正

https://github.com/NewGyu/dotnet-core/commit/341e2cc3467cdd88c156e55a095b13b2ccbfb2e5

ClrDbgデバッガのインストールスクリプトが最近変わったのかdocker build時にエラーが出ます。

ここまでで、

$ ./dockerTask.sh build debug

が、ようやく正常に完了するようになります。


VSCodeの設定ファイルにlinux用の設定を加える

ここからは私のマシンがUbuntuだから必要なのだと懐います。

(Macでは必要ないかと思われます)


tasks.jsonにlinux用の設定を加える

https://github.com/NewGyu/dotnet-core/commit/0d84807ebb91dde4426152bf27000d07ab99cd03

dockerジェネレータが吐く設定はLinux用の設定が抜けていました。

MS love Linux言ってたのに残念な感じです。


launch.jsonのlaunchBrowser設定を消し去る

https://github.com/NewGyu/dotnet-core/commit/65436e5291e9695c9493cdd4d57f0b1afa6ecf41

これは自分のPC固有の問題かもしれません。

dockerジェネレータの吐く設定では、F5を押した時に


  1. docker-composeでdockerイメージを起動

  2. ローカルでdotnetコマンドを実行

  3. docker exec でClrDbgを起動

  4. ブラウザで http://localhost:5000 を起動

となっていましたが、ブラウザ起動後にデバッグ実行が失敗してしまいます。これを入れてみたのですが、改善されず諦めた形です。

ここまで来てようやくブレークポイントを設定してデバッグ実行ができるようになりました。


プロダクション用のイメージを作る

$ ./dockerTask.sh build release

これは素直にできます。



所感

いろいろまだ発展途上な感じがします。

dotnetコマンドのインストーラのネーミングもわかりにくく、1.0系なのか1.1系なのかよくわからないネーミングです。

$ dotnet --info

.NET Command Line Tools (1.0.0-preview2-1-003177)

Product Information:
Version: 1.0.0-preview2-1-003177
Commit SHA-1 hash: a2df9c2576

$ dotnet 


Microsoft .NET Core Shared Framework Host

Version : 1.1.0
Build : 928f77c4bc3f49d892459992fb6e1d5542cb5e86

また、チュートリアルにあるyo docker(dockerジェネレータ)のメンテナンスが追いついてないように思えます。

とはいえ、冒頭にも申したとおりBetter JavaとしてのC#言語には魅力を多少感じますので、マイクロソフトとC#コミュニティの今後の発展に期待したいものです。