(第1回)【Oracle Cloud】OKE + FSSのマネージドな環境でASP.NET Core Webアプリを稼働する

(第1回)【Oracle Cloud】OKE + FSSのマネージドな環境でASP.NET Core Webアプリを稼働する

目次

はじめに
ファイルがアップロードできるASP.NET Core Webアプリを作成する
モデルを作成
ビューを作成
コントローラを作成
Dockerfileを作成
今回のまとめ

はじめに

Oracle Cloudのマネージドサービスを使ってWebアプリを稼働する環境を構築したいと思います。
アップロードしたファイルをファイルシステムに格納するシンプルな作りを想定していますが、今回はひと工夫を加えて、安定的にシステムが稼働出来るようにOKEFSSでマネージドな構成にしていきます。

OKEは Oracle Container Engine for Kubernetes というOracle Cloudで利用できるマネージドな Kubernetes サービスです。(Kubernatesとはコンテナオーケストレーションツールの1つです。K8sと略されることが多いです)

一度作ってしまえば運用が楽になり、かつ安定稼働が見込めるのでこういった最近っぽい構成をぜひ取り組んでいきたいと思った次第です。

また、前回はOracle CloudのREST APIの利用検証も記事にさせていただいておりますので、良ければご覧ください!

話を戻しまして、今回はこのような構成でクベってみたいと思います。

構成イメージ

構成イメージはこんな感じでいきたいと思います。
まずは、完成までの道のりを確認しておきます。

  • Webアプリケーションを開発する ← 今回やるのはこちらです
  • アイデンティティユーザーを作成しポリシーを設定する
  • OCIレジストリにDockerイメージを登録する
  • File Storage Serviceを設定する
  • OKEを設定する
  • 稼働!完成!

ということで「稼働!完成!」を目標に楽しみながらやっていきたいと思います!

ファイルがアップロードできるASP.NET Core Webアプリを作成する

今回の趣旨はOKE + FSSを構築することなんですが、稼働するアプリケーションが無いと寂しいですよね。
ということで第一回はアップロードされたファイルをFSSのボリュームに格納するWebアプリケーションを作成します。

ASP.NET Core Webアプリケーションを使用してアプリを作っていきましょう。
Visual Studio で新規プロジェクトを作成していきます。「ASP.NET Core Webアプリケーション」を選択します。

Visual Studio 新規プロジェクト作成

次にプロジェクト名を決めて、テンプレートを選択します。テンプレートはWebアプリケーション(モデル ビュー コントローラー)にしました。

Visual Studio プロジェクト名の設定
Visual Studio テンプレートの選択

プロジェクトが出来たらまずはモデルを追加していきます。

モデルを作成

「Models」のフォルダーの下にクラスを追加します。
「FileUploadModels」という名前にします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace FileUploadWebApp.Models
{
    public class FileUploadModels
    {
        public IFormFile PostedFile { get; set; }
    }
}

ビューの作成

「Views」フォルダーに「FileUpload」というフォルダーを作成し、その中にビューを追加します。

MVCビューの追加

作成したビューにinput要素等を追加していきます。
(別にajaxじゃなくてsubmitで良いのですが、、笑)

@model FileUploadWebApp.Models.FileUploadModels

@{
    ViewData["Title"] = "FileUpload";
}

<h1>ファイルアップロード</h1>

<hr />
<div class="row">
    <div class="col-md-10">
        <form asp-action="Upload">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <input type="file" name="postedfile" />
            </div>
        </form>
        <div class="form-group">
            <input type="button" id="ajaxUpload" value="送信" class="btn btn-primary" />
            <div id="result"></div>
        </div>
    </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script type="text/javascript">
        //<![CDATA[
        $(function () {
            $('#ajaxUpload').on('click', function (e) {
                var fd = new FormData(document.querySelector("form"));
                $.ajax({
                    url: '/FileUpload',
                    method: 'post',
                    data: fd,
                    processData: false,
                    contentType: false
                }).done(function (response) {
                    $("#result").empty;
                    $("#result").text(response);
                }).fail(function (jqXHR, textStatus, errorThrown) {
                    $("#result").empty;
                    $("#result").text('textStatus: ' + textStatus + ', errorThrown: ' + errorThrown);
                });
            });
        });
        //]]>
    </script>
}

コントローラーの作成

最後にコントローラーを追加します。テンプレートは「MVC コントローラー – 空」にします。
名前は、「FileUploadController」にします。

新規スキャフォールディング アイテムの追加
空のMVCコントローラーの追加

コントローラーの中身を書いていきます。/UploadFiles にファイルが登録されるようにしておきます。
開発しているPCはWindowsなのですが、C直下に「UploadFiles」というフォルダーを用意しておきます。

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System.IO;
using FileUploadWebApp.Models;

namespace FileUploadWebApp.Controllers
{
    public class FileUploadController : Controller
    {
        // GET: Upload
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Index(FileUploadModels model)
        {
            string result = "";
            IFormFile postedFile = model.PostedFile;

            if (postedFile != null && postedFile.Length > 0)
            {
                string filename = Path.GetFileName(postedFile.FileName);
                string filePath = "/UploadFiles/" + filename;

                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await postedFile.CopyToAsync(stream);
                }

                result = filename + " (" + postedFile.ContentType + ") - " + postedFile.Length + " bytes アップロード完了";
            }
            else
            {
                result = "ファイルアップロードに失敗しました";
            }

            // Core では Request.IsAjaxRequest() は使えない
            if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
            {
                return Content(result);
            }
            else
            {
                ViewBag.Result = result;
                return View();
            }
        }
    }
}

これで準備が出来たのでデバッグしてみます。URLに「/FileUpload」を付けてアクセスして動作を確認します。

Windows だとちゃんと動くのか気になりましたが、 C:\UploadFiles\ にちゃんとファイルが保存されてました。
「/UploadFiles」でちゃんと動くんですね!かしこいです。

Startup.cs

トップページへのアクセスは、FileUploadコントローラーを使用するように調整をしておきます。

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=FileUpload}/{action=Index}/{id?}");
            });

Dockerfileを作成

右クリック > 追加 > DockerサポートでDockerfileを生成します。
これで簡単にDockerfileが追加できました。

Dockerfileを追加

Dockerfileの内容は以下です。

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["FileUploadWebApp/FileUploadWebApp.csproj", "FileUploadWebApp/"]
RUN dotnet restore "FileUploadWebApp/FileUploadWebApp.csproj"
COPY . .
WORKDIR "/src/FileUploadWebApp"
RUN dotnet build "FileUploadWebApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "FileUploadWebApp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN mkdir /UploadFiles
ENTRYPOINT ["dotnet", "FileUploadWebApp.dll"]

注意点があります。生成されたDockerfileの場所は「.csproj」ファイルと同階層に作成されますが、docker buildを実行する際は、Dockerfileを一つ上の階層に移動させるなどの調整が必要でした。

├─FileUploadWebApp
│  ├─FileUploadWebApp.csproj
│  ├─Dockerfile ★ここに生成されている
│  ├─bin
│  ├─Controllers
│  ├─Models
│  └─obj
│
├─FileUploadWebApp.sln
│
└─Dockerfile ★ここに移動しておく

また、22行目付近に「/UploadFiles」ディレクトリを作成するように追記しました。
5-6行目のEXPOSE 80EXPOSE 443 は同じPodにNginxコンテナを起動する予定ですので不要でしたが、今回はこのまま行きました。

今回のまとめ

これでとりあえずファイルがアップロードできるWebアプリケーションが出来ました!
今回は準備編といったところでしょうか笑
さて、次回は Oracle Cloud上で色々と設定をしていきます。
今回はこれで以上となります。