【Docker】ASP.NET MVC Core 3.1+Vue.js+SQLServer(MSSQL)で環境構築

という訳で前回記事で予告した通り、今回はいよいよDockerを使ってASP.NETを使った環境構築をしてみたいと思います。とはいえ、C#が絡む開発はIDEであるVisual Stdioが優秀なのでLaravelやRailsのDocker環境作るよりもっと簡単にできました。

初回の環境はVSで自動作成するのが無難

Docker環境での構築なら環境作った後でもコマンドで挿入できるのですが、C#エンジニアならVSは絶対使っていると思うので正直VSを使った方が早いです。VSには新規プロジェクトでどの型を作りたいかである程度テンプレートを作っておりますので感覚的に環境構築ができます。

前述した通り、既に.NET 5 は出ていますが今回は.NET Core 3.1で作ります。この理由も前述した通り、.NET 5 はLTSではないのでサポート期間が短いからです。多くのC#を扱う企業も今は.NET Core 3.1が主流だと思います。(今の私の案件もそう)

Dockerfileも自動作成できる

上記プロジェクトを選ぶと次の選択で「Dockerを有効にする」を選ぶとプロジェクトが出来た時にDockerファイルも自動で作成してくれます。

このできたDockerファイルはDocker環境を作る時に必要になります。ちなみにプロジェクトを読み込むとコンソールが自動実行されて一応Docker上でもちゃんと立ち上がります。

しかし、この自動で作られたコンテナは正直あまり意味ないです。通常VSでDockerを使わない場合はIISで立ち上がりますがそれがDockerになっただけで、VS上で実行中の時しか「OPEN IN BROWSER」で画面が表示されないからです。実行してなければ押しても動作していません」と表示されてしまいます。これだけならIISデバッグでいいじゃん。。。となってしまいます。

docker-compose.ymlを作る

今度はIDEがなくてもASP.NET周りの環境をコンテナ化してWebページを表示されるようにします。

ここからは今までのLaravelやRailsで同じようにdocker-compose.ymlでDB環境やNginxの環境を整えていきます。C#環境でDB作る時はSQL Server(MSSQL)一択です。C#やASP.NET使ってる場合、DBがMSSQL以外のDBを使っている企業を見たことない。。

この環境構築は以下のサイトを参考にしました。2020年執筆で記事が新しめのため、特に詰まる所なく環境構築できました。

ASP.NET Core のWebアプリケーションを docker-compose で Dockerアプリケーション として構築する

ただし、初回実行時は最後のdocker-compose up -dだけだと、まだイメージがないので怒られてしまいます。docker builddocker-compose up –build (-は二つ) で新しくイメージを作成してから実行しましょう。でないとエラーになってしまいます。

イメージとWebページ表示

無事コンテナが立ち上がったらあとはRailsやLaravelの時と同じく、Webの所で「OPEN IN BROWSER」ボタンを押せばWebページが立ち上がります。

これでASP.NETを使ったDockerの立ち上げは完了しました。ただ、上記解説サイトにもありましたがC#の場合はAzureを使えば簡単にWeb公開できるのでDockerを介す意味はあるのか?という疑問もありますね。ただ、AWSと同じくAzureもずっと無料で使えるわけではなかった気が?(公式サイトでは1年は無料と記載あり)

HerokuサーバにDocker環境立ち上げてデプロイしても表示されるはずでこっちは永続的に無料なのでポートフォリオサイトとして永遠に公開していたい場合はそっちをお勧めしたいです。

ASP.NETにVue.jsを入れる

それではサンプルサイトが立ち上がりましたので今度はその環境でVue.jsが動くようにしたいと思います。しかし新規プロジェクトの一覧ではAngularReact.jsと組み合わせたサンプルはありますが残念ながらVue.jsはありません・・・後発だから対応していないのかしら?

とはいえ、今からJavaScriptのフレームワークをやるならVue.jsをやった方がいいです。なので別途インストールすることになりますが、こちらも以下のサイトを参考に実装させていただきました。

ASP.NET Core で Vue.js を使用する

この記事で補足があるとすれば_Layout.cshtmlの一文がどこに追記するかが書かれてなかったので以下のように記述しました。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Aspnet_System_master</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Aspnet_System_master</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - Aspnet_System_master - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
        <script src="~/lib/vue/vue.js"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
        </script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o">
        </script>
        <script src="~/lib/vue/vue.min.js"></script>
    </environment>
    @RenderSection("Scripts", required: false)
</body>
</html>

index.cshtml

@{
    ViewData["Title"] = "Home Page";
}

<div id="app">
    {{ message }}
</div>

@section Scripts {
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                message: 'Hello Vue!'
            }
        })
    </script>
}

とはいえ、これだけを直しただけで表示されました。う~ん。Railsの時にあんな苦戦したのがウソのようだ。。。

あとはDocker上のWebページに反映するには再度docker buildを実行してからcompose upでコンテナを立ち上げればVue.jsを反映したページが表示されます。

まとめ

これでRailsとLaravelとASP.NET Core MVC で基本環境を立ち上げられた事になりますC#は元々専用といってもいいIDEがあるのでDockerを使う恩恵がなかったような・・・Web公開となればまた話は別ですけどね^^;

対してRailsやLaravelは専用のIDEみたいなのものがないのでDocker Desktop for Windowsを使ってデバッグ環境を構築する価値があると思います。一番の利点は構築やファイルを壊してしまっても簡単にやり直しが効くことですからね。

でやった時のWordPress環境はAWSのAmazon Linux 2を使いましたが環境構築に失敗して詰まった時はEC2を止めて削除してまた作成、AZ(アベイラビリティーゾーン)もろもろ選び直し・・・という作業が非常に面倒でした。。。それにひきかえDocker上なら失敗したらそのコンテナに関するイメージを削除すればいいだけなので非常に簡単です!ホントに便利なツールだなぁと思いました。

次回の記事は実際にSQLSERVERから取得した値を実際に画面に表示させたいと思います。興味があれば下記リンクから直接記事に飛べます。