VSCode Remote Containersで.NET Core + MySQL + Elasticsearchの開発環境構築

現在参画しているプロジェクトにて、全文検索機能の要件があったため、既存の構成＋Elasticsearchの環境構築をしてみました。
今回は開発環境構築の部分についてご紹介しようと思います。

#はじめに
今回ご紹介するのはあくまで開発環境用の最小構築であり、運用環境の構築にそのまま転用できる内容ではないことを予めご了承ください。

#環境
- MacBook Pro 10.15.7
- VSCode 1.50.1
- Docker 19.03.13
- Docker For Mac 2.4.0.0
- Docker image version
    - mysql:8.0
    - sebp/elk:oss-792
    - mcr.microsoft.com/dotnet/core/sdk:3.1

#ソースコード
https://github.com/t-ash0410/asp.net-core-sample

#ディレクトリ構成
> root/
├ .devcontainer/
　├ db/
　　├ init/
　　└ create_db.sql
　　　└ my.conf
　├ devcontainer.json
　└ docker-compose.yml

create_db.sqlとmy.confに関しての説明は割愛します。

#docker-compose.yml

```yml:docker-compose.yml
version: '3'

services:
  dotnet_db:
    image: mysql:8.0
    container_name: dotnet_db
    ports:
      - "3306:3306"
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: password
    volumes:
      - "db_data:/var/lib/mysql"
      - "./db/my.conf:/etc/mysql/my.conf"
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --skip-character-set-client-handshake

  dotnet_elk:
    image: sebp/elk:oss-792
    container_name: dotnet_elk
    ports: 
      - "5601:5601"
      - "9200:9200"

  dotnet_web:
    image: mcr.microsoft.com/dotnet/core/sdk:3.1
    container_name: dotnet_web
    ports:
      - "8080:8080"
    environment:
      DB_CONNECTION_STRING: "server=dotnet_db;port=3306;uid=root;pwd=password;database=asp_net_sample"
      ELASTIC_SEARCH_SERVER: "http://dotnet_elk:9200"
    volumes:
      - "../:/dotnet-app"
    command: /bin/bash -c "while sleep 1000; do :; done"

volumes:
  db_data:
    driver: local
```

###各項目について

<dl>
  <dt>image</dt>
  <dd>作成するコンテナのイメージを指定<br>
　</dd>

  <dt>container_name</dt>
  <dd>作成するコンテナ名を指定<br>
　</dd>

  <dt>ports</dt>
  <dd>公開するポートを指定<br>
今回の形式は <code>ホストマシンのポート:コンテナのポート</code> での指定となります。<br>
　</dd>

  <dt>environment</dt>
  <dd>環境変数の宣言<br>
　</dd>

  <dt>volumes</dt>
  <dd>ボリュームのマウント<br><br>
<code>相対パス:絶対パス</code>の形式は、ホストマシン上の相対パスをコンテナ上の絶対パスにマウントしています。<br>
この場合に指定する相対パスはdocker-compose.ymlが配置してあるディレクトリからの相対パスである必要があります。<br><br>
<code>volumesに定義したkey:絶対パス</code>の形式は、volumesに定義されたkeyに該当するdata volumeをコンテナ上の絶対パスにマウントしています。<br>
　</dd>

  <dt>command</dt>
  <dd>コンテナのセットアップ完了後に実行されるコマンドを指定
　</dd>
</dl>

#devcontainer.json
```devcontainer.json
{
	"name": "books app",
	"dockerComposeFile": [
	  "docker-compose.yml"
	],
	"workspaceFolder": "/dotnet-app",
	"service": "dotnet_web",
	"extensions": [
		"ms-dotnettools.csharp",
		"jmrog.vscode-nuget-package-manager",
		"ms-azuretools.vscode-docker",
		"p1c2u.docker-compose"
	],
	"settings": {
	  "editor.tabSize": 2,
	  "files.insertFinalNewline": true,
	  "files.trimFinalNewlines": true,
	  "terminal.integrated.shell.linux": "/bin/bash"
	},
	"shutdownAction": "none"
}
```


###各項目について

<dl>
  <dt>name</dt>
  <dd>作成するアプリケーション名を指定<br>
　</dd>

  <dt>dockerComposeFile</dt>
  <dd>dockerコンテナの作成に使用するdocker-composeファイルを指定<br>
　</dd>

  <dt>workspaceFolder</dt>
  <dd>ワークスペースの展開先ディレクトリを指定<br>
　</dd>

  <dt>service</dt>
  <dd>vscodeで接続するserviceの指定<br>
　</dd>

  <dt>extensions</dt>
  <dd>開発時に利用するvscodeのextensionを指定<br>
　</dd>

  <dt>settings</dt>
  <dd>vscodeの格設定を指定<br>
　</dd>

  <dt>shutdownAction</dt>
  <dd>vscode終了時のコンテナに対するアクションを記述<br>
noneの場合、vscodeが終了後もコンテナが起動したままとなります。
　</dd>
</dl>

#起動確認

1. vscodeを開く
2. command + shift + P
3. >Remote-Containers: Rebuild and Reopen in Container
4. 正常に立ち上がれば成功

#link
###公式ドキュメント
[docker-compose](https://docs.docker.jp/compose/toc.html)
[ASP.NET Core向けのDocker イメージ](https://docs.microsoft.com/ja-jp/aspnet/core/host-and-deploy/docker/building-net-docker-images?view=aspnetcore-3.1)
[elk-docker](https://elk-docker.readthedocs.io/#prerequisites)
[Developing inside a Container using Visual Studio Code Remote Development](https://code.visualstudio.com/docs/remote/containers)

###参考にさせていただいた記事
[【2020年1月】令和だし本格的にVSCodeのRemote Containerで、爆速の"開発コンテナ"始めよう](https://qiita.com/koinori/items/084a0770c1f9e72e0c14)
[DockerでMySQLを使ってみる](https://qiita.com/TAMIYAN/items/ed9ec892d91e5af962c6)
[初めてのElasticsearch with Docker](https://qiita.com/kiyokiyo_kzsby/items/344fb2e9aead158a5545)

#続き
アプリケーションコードについて

- [.NET Core + MySQL + Elasticsearch(Nest)構成でクリーンアーキテクチャなバックエンド開発](https://qiita.com/ashicom/items/1f4ff3fd15193d6388e0)

AWS上で環境構築してみた

- [【AWS入門】EC2インスタンス上に.NET Core + nginx環境を構築](https://qiita.com/ashicom/items/c91d65dd5b3a2d23c7ae)
- [【AWS入門】RDSでMySQL環境を構築してEC2上のWebアプリと連携](https://qiita.com/ashicom/items/d60d8372ef7509557c74)
- [【AWS入門】AWS Elasticsearch Serviceを構築してEC2上のWebアプリと連携](https://qiita.com/ashicom/items/cc45c1cdcb545e242035)

その他番外編的に書こうと思ってるやつ

- CircleCIを利用した.NET Coreアプリの自動デプロイ
- Docker Composeを利用したELKスタック環境構築
- Elasticsearchの部分をCloudsearchに置き換える