Visual StudioのコードとDockerを使用して同じようにASP.NETコアアプリを開発する 

このガイドでは、Ubuntu Linuxデスクトップ上でVisual Studio Codeを使用して**ASP.NET**コアアプリを開発し、**Alibaba Cloud**上で**Docker**を使用して同じアプリをデプロイします。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/developing-asp-net-core-apps-using-visual-studio-code-with-docker-on-simple-application-server_595353)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#よくある質問
####.NET coreとは？
.NET Core は、Microsoft と .NET コミュニティによってメンテナンスされているオープンソースの汎用開発プラットフォームです。クロスプラットフォーム（Windows、MacOS、Linuxをサポート）であり、デバイス、クラウド、IoTアプリケーションの構築に使用できます。

####ASP.NET coreとは？
ASP.NET Coreは、クロスプラットフォーム、高性能、オープンソースのフレームワークで、最新のクラウドベース、インターネットに接続されたアプリケーションを構築するためのフレームワークです。

####Dockerとは？
Dockerは非常に人気のあるコンテナプラットフォームで、アプリケーションやサービスを簡単にパッケージ化、デプロイ、消費することができます。

####Visual Studio Codeとは？
Visual Studio Codeは、デスクトップ上で動作する軽量かつ強力なソースコードエディタで、Windows、MacOS、Linuxに対応しています。JavaScript、TypeScript、Node.jsをビルトインでサポートしており、他の言語（C++、C#、Java、Python、PHP、Goなど）やランタイム（.NET、Unityなど）に対応した拡張機能の豊富なエコシステムを備えています。Visual Studio Codeでは、Dockerを使用したアプリケーションのデプロイを簡単に行うことができ、プロジェクトの種類に応じて適切なDockerファイルの生成と追加をサポートしています。


####Alibaba Cloud Simple Application Serverとは？
Simple Application Serverは、アプリケーションの起動と管理、ドメイン名解決の設定、Webサイトの構築、監視、保守を数回クリックするだけで行えるオールインワンのソリューションを提供します。プライベートサーバーの構築が格段に簡単になり、初心者がアリババクラウドを始めるのに最適な方法です。

#アプリケーションの開発例
####Ubuntu Linuxデスクトップに前提条件をインストール
私はバージョン16.04のUbuntu Linuxデスクトップを持っています。記載されている手順は、どのバージョンでもほとんど同じです。

####Node.js
node.jsがインストールされているかどうかを確認します。


```
node –v
```

バージョン番号が表示されない場合は、以下の手順でインストールしてください。

```
sudo apt-get install curl python-software-properties
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash –
sudo apt-get install nodejs
```

ノードとnpmのバージョンを確認します。

```
node –v
npm –v
```

####.net core sdk
次のコマンドを実行して、.net core sdkをインストールします。


```
wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2
```

注：あなたがUbuntu 16.04 - x64とは異なるlinuxのバージョンを持っている場合は、[https://dotnet.microsoft.com/download/linux-package-manager/ubuntu16-04/sdk-current]() に移動し、linuxのバージョンを変更します。

Docker

DockerにはEnterprise版とCommunity版があります。今回はコミュニティ版のDocker CEをインストールします。

以前のバージョンがインストールされているかどうかを確認し、インストールされている場合はアンインストールしてください。

```
sudo apt-get remove docker docker-engine docker.io containerd runc
```

aptパッケージを更新します。

```
sudo apt-get update
```

aptがHTTPSでリポジトリを使用できるようにします。


```
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
           gnupg-agent \
    software-properties-common
```

GPGキーを追加します。


```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –
```

安定版リポジトリを設定してインストールします。

```
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

dockerをインストールします。

```
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
```

hello-worldイメージを実行して、Dockerが正しくインストールされているか確認します。

```
sudo docker run hello-world
```

このコマンドはイメージをダウンロードしてコンテナ内で実行し、そのコンテナ内でHello Worldを印刷します。

しかし、上記のコマンドは sudo または root ユーザーのアクセスで実行されています。

次にインストールする Visual Studio Code とその docker 拡張モジュールを IDE として使用する予定なので、非 root ユーザで実行できるようにする必要があります。VS Code は非 root ユーザーで実行され、拡張機能によりコンテナ化されたアプリケーションの構築、管理、デプロイが容易になります。

dockerグループを作成します。

```
sudo groupadd docker
```

dockerグループにユーザーを追加します。

```
sudo usermod -aG docker $USER
```

ログアウトして再度ログインするか、グループのメンバーシップが再評価されるように再起動してください。

sudo 再起動
再起動後、sudoなしでdockerコマンドが実行できることを確認します。

```
docker run hello-world
```

####Visual Studioコード
VS Code をインストールする最も簡単な方法は、Snap パッケージとしてインストールすることです。スナップはすべての主要な Linux ディストリビューションで使用することができ、ほとんどの Ubuntu デスクトップにプリインストールされています。もしあなたのデスクトップにない場合は、[https://docs.snapcraft.io/installing-snapd](https://snapcraft.io/docs/installing-snapd?spm=a2c65.11461447.0.0.1b691fbfmkOFSE) からインストールすることができます。

を実行してVSコードをインストールします。

```
sudo snap install --classic code
```

アプリケーション/プログラミングから同じものを選択するか、linuxターミナルでコードを入力してVisual Studioのコードを開きます。

表示」→「拡張機能」に移動します。

C# for Visual Studio Code (powered by OmniSharp)」を検索し、拡張機能をインストールします。拡張機能の詳細については [https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) を参照してください。

Docker」を検索して、拡張機能をインストールします。拡張機能の詳細は [https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker](https://marketplace.visualstudio.com/items?spm=a2c65.11461447.0.0.1b691fbfmkOFSE&itemName=ms-azuretools.vscode-docker) を参照してください。

####.NETコアプロジェクトを作成
フォルダを開くを選択し、documentsディレクトリに移動します。ここでプロジェクトを作成します。

VS Codeにはシェルコマンドを実行するためのターミナルが統合されています。そこから直接.NET Coreのコマンドラインインターフェイス(CLI)コマンドを実行することができます。

Visual Studio Codeのトップメニューから「ターミナル」→「新規ターミナル」を選択してターミナルを開きます。

利用可能なテンプレートの一覧を取得してみましょう。

```
dotnet new -l
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/40d55053-895d-a5e5-96a3-f7f2ba147b74.png)

数あるプロジェクトテンプレートの中から、新しいASP.NET Core MVC Appを作成してみましょう。

```
dotnet new mvc -n dotnetcore-alibaba-docker-tutorial --no-https
```

上記のコマンドは、ベースアプリケーションを作成し、dotnetcore-alibaba-docker-tutorialというフォルダ内にASP.NET Core 2.2 MVCアプリケーションをスキャフォールドします。'--no-https' コマンドオプションを使用すると、プロジェクト作成時に https をオプトアウトすることができます。コマンドやその他の利用可能なオプションについての詳細は [https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new?tabs=netcore22](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new?spm=a2c65.11461447.0.0.1b691fbfmkOFSE&tabs=netcore22) を参照してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/ac70dc1b-38a0-bf04-ad12-443b197df71a.png)

Visual Studio Codeのトップメニューから「ファイル」→「フォルダを閉じる」を選択して、VS Codeでアプリケーションを閉じます。

####コードの編集と変更
ここに独自の開発コードを追加します。ここでは、いくつかの簡単な変更を行います。

Open Folderを選択し、documentsフォルダの下にあるdotnetcore-alibaba-docker-tutorialフォルダに移動し、アプリケーションを開きます。

欠けているアセットを追加するように促されます (`Require assets to build and debug are missing`)。これは.vscodeフォルダで、同じlaunch.jsonとtask.jsonの中に、F5でアプリケーションを起動してデバッグすることができるようになっているので、Yesボタンをクリックするだけです。

左側のペインから、ビュー→ホーム→index.cshtmlを選択します。

'Welcome'という単語を'Welcome to Docker on Simple Application Server'に更新します。

ビュー→共有→layout.cshtmlを選択します。

dotnetcore_alibaba_docker_tutorial」のすべてのインスタンスを「Alibaba Cloud」に更新します。インスタンスは3つあり、1つはタイトル、1つはナビバー、そして最後の1つはフッターになります。

####アプリケーションの実行
F5ボタンを押してアプリケーションを実行します。

アプリケーションが実行され、Webアプリケーションが http://localhost:5000 に表示されます。

注意：最新の.NET Coreでは、開発アプリケーションはhttpsで動作します。そのため、''--no-https' コマンドオプションを付けずにプロジェクトを作成し、アプリケーションを実行した場合、接続がプライベートではないという警告が表示されます。そのような場合は、[詳細設定]ボタンをクリックし、[ローカルホストに進む(安全ではない)]をクリックして、http://localhost:5001 にある Web アプリケーションを表示します。

Visual Studio Codeのトップメニューから「ファイル」→「フォルダを閉じる」を選択して、VS Codeでアプリケーションを閉じます。

#アプリケーションをDockerizeする例
パブリックリポジトリは、誰もが利用できるDockerイメージをホスティングするために使用することができます。Docker hubはパブリックリポジトリであり、利用するためのパブリックなDockerイメージのリストを見つけることができます。必要なのはそれらのイメージを引っ張ってきて、それを元にコンテナを起動し始めることだけです。また、Alibaba Cloudは、高速で信頼性が高く、安全なプライベートコンテナレジストリを提供しています。[https://www.alibabacloud.com/product/container-registry](https://www.alibabacloud.com/ja/product/container-registry)私たちは、このプライベートリポジトリにイメージを公開することで、イメージを利用可能にしています。


####Alibaba Cloudコンテナレジストリアカウントの作成

####アリババクラウドコンテナレジストリアカウントとリポジトリの作成
アリババクラウドアカウントをお持ちでない方は、[https://account.alibabacloud.com/register/intl_register.htm](https://account.alibabacloud.com/register/intl_register.htm?spm=a2c65.11461447.0.0.1b691fbfmkOFSE) で無料で取得できます。

コンソールに移動し、[製品]の下の[コンテナレジストリ]を選択します。

パスワードを入力して確認し、Alibaba Cloud Container Registryを有効化します。このパスワードは、クラウドアカウントとは異なるコンテナレジストリ用のパスワードです。

これで、以下のようにコンテナレジストリのコンソールが表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/91366929-d367-b05e-da6d-a9794d871514.png)

ネームスペースはリポジトリの集合体、リポジトリはイメージの集合体です。アプリケーションごとにネームスペースを、イメージごとにリポジトリを用意します。1つのイメージのすべてのバージョンが1つのリポジトリに入ります。

左メニューのDefault InstanceからNamespacesを選択し、Create Namespaceボタンをクリックします。

下の画像のようにネームスペースを入力し、確認ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b225ef0d-6da2-7801-b485-e42ce1c286a9.png)

ネームスペースが作成されます。自動的にリポジトリを作成するオプションをオフにします。

左メニューからリポジトリに戻り、リポジトリの作成を選択します。

リポジトリ名を入力し、リポジトリタイプをプライベートのままにして、サマリーテキストを入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/65b4b3a9-ff93-51e0-eb1a-5c11d116310c.png)

次の画面で、コードソースとしてローカルリポジトリを選択し、リポジトリの作成をクリックします。

Container Registryでは、Alibaba Cloud Code、Github、Bitbucketなどのソースコードリポジトリを使用して、イメージの自動ビルドを作成することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/a03d19b1-ba46-7a56-0119-b071df1d4f17.png)

作成したリポジトリで、リポジトリ名をクリックします。

この画面を通過し、リポジトリへのログイン、画像のプル、プッシュに必要なコマンドを学習します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/851d8d21-c1ca-e9da-e646-598c99bdf862.png)

#アプリケーションをDockerizeする
フォルダを開くを選択し、documentsフォルダの下にあるdotnetcore-alibaba-docker-tutorialフォルダに移動し、アプリケーションを開きます。

Visual Studio Codeのトップメニューから「ターミナル」→「新規ターミナル」を選択してターミナルを開きます。

Dockerがインストールされて実行されていることを確認します。

```
docker --version
```

Visual Studio CodeのトップメニューからView->Command Paletteを選択してCommand Paletteを開きます。

ワークスペースにDockerファイルを追加と入力し、Dockerを選択して実行します。Docker ファイルをワークスペースに追加 コマンドを実行します。

コマンドパレットでアプリケーションプラットフォームの選択を求められますので、ASP.NET Coreを選択します。

次のコマンドパレット画面で、オペレーティングシステムとして linux を選択します。

また、アプリケーションがリッスンするポートを指定してください。

これは、ソースファイルの場所やコンテナ内でアプリを起動するコマンドを含むアプリの環境を記述するDockerfileと共にプロジェクトに特定のファイルを追加します。DockerIgnoreファイルは、ビルドコンテキストを可能な限り小さく保つのに役立ちます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/37d89690-9499-b9f9-fbec-b81e53bcec73.png)

dockerfileで何が起こっているのかを理解してみましょう。

まず、アプリケーションのビルドに必要なパッケージと依存関係を復元します。次に、アプリケーションをビルドし、/appディレクトリに公開します。この段階では、Microsoft Container Registry (MCR)で利用可能な.NET Core SDKをベースイメージとして使用します。

次に、ベースイメージとして.NET Core Runtimeを使用し、前の段階で生成したバイナリを/appディレクトリからコピーします。ENTRYPOINT内のアセンブリ名は大文字と小文字を区別し、binDebugフォルダ内のアセンブリ名と一致させる必要があります。

コマンドパレットでDocker: Build Imageを実行してイメージをビルドします。名前を聞かれたらデフォルトの名前を受け入れてください。イメージには[projectname]:latestというタグが付けられます。

ターミナルパネルが開き、Dockerコマンドが実行されます。ビルドが完了すると、DockerのエクスプローラのImagesの下にイメージが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/c1f09c44-d396-0f60-e5ba-69eaf4b85ecf.png)

コマンドパレットでdocker runと入力し、Docker:Images runを選択してコンテナをビルドします。

コマンドパレットで、イメージグループ「dotnetcore-alibaba-docker-tutorial」を選択します。

コマンドパレットで、画像の「最新」を選択します。

ターミナルに表示された生成されたコマンドを実行します。

コマンドは'docker run'で、2つのフラグがあります。

-p : これはコンテナ上のポートを公開し、ホスト上のポートにマッピングします。ここでマッピングされたホスト上のポートも同様に5000です。

-d : バックグラウンドでコンテナを実行します。

詳細は [https://docs.docker.com/engine/reference/commandline/run/](https://docs.docker.com/engine/reference/commandline/run/?spm=a2c65.11461447.0.0.1b691fbfmkOFSE) を参照してください。

お使いのブラウザで http://your_server_ip:5000 または http://localhost:5000 に移動して、アプリケーションを表示します。

残念ながらウェブサイトは表示されません。

実行中のコンテナを検査します。

```
Docker ps
```

コンテナログを検査します。

```
Docker logs [CONTAINER ID] 
```

CONTAINER ID]を`Docker ps`コマンドで取得した自分のCONTAINER IDに置き換えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/7eeafbf5-b986-dce2-2c50-7af15710b1e8.png)

ログを見ると、デフォルトでは80番ポートでリッスンされています。

mcr.microsoft.com/dotnet/core/aspnet:2.2 イメージは ASPNETCORE_URLS をポート 80 に設定しています。

実行中のコンテナを右クリックして、DOCKER explorer の Containers の下にある stop を選択して、実行中のアプリケーションコンテナを停止してください。

または、ターミナルで以下のコマンドを実行することもできます。

```
docker stop [CONTAINER ID]
```

以下のようにDockerfileを更新して、kestrelのWebサーバがリッスンするURLを明示的に指定します。

```
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
ENV ASPNETCORE_URLS http://+:5000
EXPOSE 5000

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src
COPY ["dotnetcore-alibaba-docker-tutorial.csproj", "./"]
RUN dotnet restore "./dotnetcore-alibaba-docker-tutorial.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "dotnetcore-alibaba-docker-tutorial.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "dotnetcore-alibaba-docker-tutorial.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "dotnetcore-alibaba-docker-tutorial.dll"]
```

コンテナをビルドして先ほどと同じように実行し、今回はブラウザから http://your_server_ip:5000 または http://localhost:5000 に移動してアプリケーションを表示できるようになります。

####Alibaba Cloud Container Registryに画像をアップロード
Visual Studio Code のトップメニューから Terminal -> New Terminal を選択して Terminal を開きます。

Alibaba Cloud Container Registry Repository Guideで利用可能だったコマンドに従ってください。

コンテナレジストリにログインします。

```
sudo docker login --username=arnab@xyz.abc registry-intl.ap-southeast-1.aliyuncs.com
```

利用可能な画像を見ます。

```
sudo docker images
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/4afd2d4b-dcbf-1292-dc54-5abcc7457e40.png)

画像にタグを付けます。

```
sudo docker tag 183d85283e0b registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1
```

画像をコンテナレジストリにプッシュします。

```
sudo docker push registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1453060a-c980-2230-aab8-ad6f8bed5857.png)

Alibaba Cloud Container Registry Consoleで、指定したリポジトリとタグのセクションで、イメージが存在することを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/94e577d2-59d8-6acf-f52f-5b68b7ae8acb.png)

#シンプルなアプリケーションサーバにアプリケーションをデプロイする
並行記事[Developing ASP.NET core App in Visual Studio and Deploying on Simple Application Server](https://www.alibabacloud.com/blog/developing-asp-net-core-app-in-visual-studio-and-deploying-on-simple-application-server_594542?spm=a2c65.11461447.0.0.1b691fbfmkOFSE)をご覧いただき、Alibaba Cloud上にCentOS7でSimple Application Serverインスタンスを作成し、インスタンスへのパスワードを作成し、デスクトップ端末を使ってログインする方法をご紹介します（記事のようにputtyではなく）。

####サーバーに前提条件をインストールする
yum
yumは、CentOSでソフトウェアパッケージを取得、インストール、削除、クエリ、管理するための主要なツールです。まず、ソフトウェアリポジトリを最新のバージョンにアップデートするために使います。

```
yum -y update
```

####Docker
古いバージョンがある場合は、アンインストールしてください。

```
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
```

必要なパッケージをインストールします。

```
sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
```

インストールするリポジトリの設定

```
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
```

Dockerのインストール

```
sudo yum install docker-ce docker-ce-cli containerd.io
```

Dockerの起動

```
sudo systemctl start docker
```

Dockerを非rootユーザーで動作させます。

```
sudo groupadd docker
sudo usermod -aG docker $USER
sudo reboot
```

Dockerの再起動

```
sudo systemctl start docker
```

コマンドが sudo なしで実行されているかどうかを確認します。

```
docker run hello-world
```

####アプリケーションのデプロイ
コンテナを構築してアプリケーションを実行します。

コンテナレジストリへのログイン

```
docker login --username=arnab@xyz.abc registry-intl.ap-southeast-1.aliyuncs.com
```

レジストリからイメージを取り出します。

```
docker pull registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1
```

アプリケーションの実行します。

```
docker run -d -p 80:5000 registry-intl.ap-southeast-1.aliyuncs.com/alibaba-docker-tutorial/dotnetcore:0.1
```

ここでは、ホスト側で80番ポートを使用しました。そのため、簡易アプリケーションサーバの公開IP（サーバ管理画面で利用可能）を利用してサイトを閲覧する際には、ポート番号を使用する必要はありません。

http://public_ip にアクセスしてサイトをテストします。アプリケーションが動作しているのが確認できるはずです。

#結論
これらは、Ubuntu linux上でビジュアルコードを使用してASP.NET Coreアプリケーションを開発し、アプリケーション用のDockerイメージを作成し、Alibaba Cloudのコンテナレジストリを作成してコンテナレジストリにイメージをプッシュし、最後にCentOSを使用してAlibaba Cloudの[Simple Application Server](https://www.alibabacloud.com/ja/product/swas)上にコンテナレジストリイメージをデプロイするための基本的なステップです。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*