VSCodeの開発コンテナで.NET Core開発環境

すごく簡単。

# 環境

* Windows 10 Pro (Dev 21370.1)
* Visual Studio Code 1.55.2

<details><summary>Docker DesktopとWSL</summary><div>

* WSL 2
* Docker Desktop 3.3.1(63152)
  * Engine: 20.10.5
  * (Use the WSL 2 based engine)

```
❯ wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         2
  docker-desktop         Running         2
  docker-desktop-data    Running         2
```

</div></details>

# WSL上で作業ディレクトリ作成

WSLから`code`コマンドを使って、**WSLのファイルシステム上に作った**ディレクトリを開く。

```
$ mkdir -p workspace/dotnetcore/example
$ cd workspace/dotnetcore/example
$ code .
```

# VSCodeで.NET Core用のテンプレートを生成

コマンドパレットから `Remote-Containers: Add Development Container Configuration Files...` を実行。
`C#`を選択し.NET Coreのバージョンを選択、`OK`を押す。
作業ディレクトリ内に`.devcontainer`ディレクトリが作成され、devcontainer用のテンプレートが保存される。

```
└─.devcontainer
    │  devcontainer.json
    │  Dockerfile
    │
    └─library-scripts
            azcli-debian.sh
```

# テンプレートをカスタマイズ（必要に応じて）

テンプレートで生成されるdevcontainerは、コンテナ内にnon-rootのユーザー`vscode (1000:1000)`が用意されている。
ユーザーを追加したい、ユーザーIDやユーザー名を変えたい、といった場合は、`Dockerfile`と`devcontainer.json`を編集する。
以下は、ユーザー名`vscode`はそのままに`UID`と`GID`を変更する例。

<details><summary>Dockerfile（追記）</summary><div>

```Dockerfile
ARG ORG_USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN groupmod --gid $USER_GID $ORG_USERNAME \
    && usermod --uid $USER_UID --gid $USER_GID $ORG_USERNAME \
    && chown -R $USER_UID:$USER_GID /home/$ORG_USERNAME \
    && apt-get update \
    && apt-get install -y sudo \
    && echo $ORG_USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$ORG_USERNAME \
    && chmod 0440 /etc/sudoers.d/$ORG_USERNAME

USER $ORG_USERNAME
```

</div></details>

<details><summary>devcontainer.json（抜粋）</summary><div>

```json
  "build": {
    "args": {
      "ORG_USERNAME": "vscode",
      "USER_UID": "1000", // ここを任意に変更
      "USER_GID": "1000"  // ここを任意に変更
    }
  },
```

</div></details>

# devcontainerを起動

コマンドパレットから `Remote-Containers: Reopen in Container` を実行。
イメージのビルドからコンテナの実行までが自動で行われる。
デフォルトで、作業ディレクトリがコンテナ上の`/workspaces/ディレクトリ名`にマウントされる。
（この例では`~workspace/dotnetcore/example`が`/workspaces/example`にマウントされる）
ちなみに、マウントのオプションは`type=bind,consistency=cached`のようだ。

VSCodeで新しいターミナルを起動して、ユーザーやバージョンを確認。

```
vscode ➜ /workspaces/example $ whoami
vscode
vscode ➜ /workspaces/example $ id
uid=1000(vscode) gid=1000(vscode) groups=1000(vscode),999(nvm)
vscode ➜ /workspaces/example $ dotnet --version
3.1.408
```

# プロジェクト作成

```
vscode ➜ /workspaces/example $ dotnet new web
The template "ASP.NET Core Empty" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on /workspaces/example/example.csproj...
  Determining projects to restore...
  Restored /workspaces/example/example.csproj (in 138 ms).

Restore succeeded.

# ついでに.gitignore生成
vscode ➜ /workspaces/example $ dotnet new gitignore --force
The template "dotnet gitignore file" was created successfully.
```

F5キーでデバッグ実行可能。ブラウザが開いて`Hello World!`が表示される。

# 参考

* [VSCode+WSL2+Dockerによるリモート開発環境の構築 (devcontainer.json概訳付き) - Qiita](https://qiita.com/y-na-biz/items/af0137532e6e22802f25)
* [VSCode Dev Container on WSL2のPermission問題メモ - Qiita](https://qiita.com/noonworks/items/472008c25a20d0598505)