Docker DesktopとWSL2のセットアップ（`クラスが登録されていません`エラー対応）

## 概要
Windows PC上で、WSL2にてDocker環境を整えるための手順を記載します。Dockerの導入は、Docker Desktopのインストールを通じて行います。

ゴールは、VSCodeからWSL2に接続して、Dockerコマンドが通る（= WSL2でDockerを使った開発ができる）ところまで。宗教上の理由からUbuntuのディストリビューションをインストールしますが、Docker Desktopデフォルトのディストリビューションでも動作するので、不要であればそこは読み飛ばしてください。

## 前提条件
### 使用するOS、ツール類
* WSL2で稼働するLinux OS：Ubuntu 22.04 LTS
* Docker：Docker Desktopから有効化するDocker Engine
* 構築したWindowsのバージョン：23H2（OS ビルド 22631.4249）

WSL2のセットアップ方法は、Windows OSのバージョンによって変わるようです。

普通にWSL2のインストール方法をググるとMicrosoftの「[WSL を使用して Windows に Linux をインストールする方法](https://learn.microsoft.com/ja-jp/windows/wsl/install)」がヒットしますが、今回構築したPCでは動作しませんでした。さらに、古い手順として残っている[以前のバージョンの WSL の手動インストール手順](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual)の内容でも動作しなかったので、必要な手順をさらに追加して、最初から最後まで記載します。

## WSL2のセットアップ
### Windows側の設定を変更する
あらかじめ、Windowsの設定にて仮想環境を使えるよう、設定を変更しておく必要があります。
* Windowsの検索に「機能」と入れる→以下の検索結果をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/f23bb5f1-d822-a8f0-faa5-b5f462acb9e2.png)
* コントロールパネルから `プログラム` > `プログラムと機能` > `Windowsの機能の有効化または無効化` を選択します。

### WSL2を使うために必要な項目を有効化する
設定画面から、`Linux 用 Windows サブシステム`と`仮想マシン プラットフォーム`にチェックを入れ、OKをクリックします。設定反映のために、PCを再起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/f9cce647-55e4-933b-15e5-cffe2fba0cf4.png)

### Linux カーネル更新プログラム パッケージを実行する
この[リンク](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)を踏むと、最新のWSL2向けLinuxカーネルがダウンロードできるので、ダブルクリックで実行します。画面の指示どおりに進んでけば大丈夫。

### WSLをインストールする
通常であれば、ここでPowerShellからコマンドを実行すればよいのですが、今回は上手くいきませんでした。エラーの内容と回避策を記載します。

#### エラー内容：クラスが登録されていません
Windows PowerShellを管理者権限で開き、`wsl --install`を実行すると、以下のエラーが発生しました。
```text
REGDB_E_CLASSNOTREG　クラスが登録されていません
```

#### 回避策：GithubからWSL2インストーラを入手、実行
GithubでMicrosoftが公開している[WSLリポジトリ](https://github.com/microsoft/WSL/releases/)から、最新版のインストーラを入手、実行しました。

今回の構築時点では、最新版は2.3.24。名称が`wsl.x.x.x.x.x64.msi`形式のファイルを選択します。`arm64`と記載があるものは、Intel CPUではなくARM製CPUが動作するWindows向けなので、該当する端末であればこちらを選べばよさそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/76554582-517d-66fe-7cc7-7405e199b857.png)

ダウンロードしたmsiファイルをダブルクリックして実行、インストールが終わったら、PowerShellを管理者として実行、`wsl --status`を実行します。以下のように表示されればOK。
```
既定のバージョン: 2
```
### Ubuntuをインストールする（必須ではないです）
WSLをインストールした時点では、まだLinux OSの本体（ディストリビューション）が導入されていません。ここでは、今後のコンテナ実行環境に利用するディストリビューションとして、Ubuntuをインストールします。要らん人は飛ばしてください。

#### Ubuntuの選定理由
後述するDocker Desktopのインストールによって、Docker ディストリビューションがインストールされますが、以下の理由からUbuntuを用いて開発を行うことにしました。

* コミュニティサポートが強力（要するに、広く使われている）なので、コマンドやエラー発生時の調査において有利
* docker desktopインストール時に入ってくる物は独自のカスタマイズなどされている可能性もあり、ハマったときに情報が無くて困りそうなので避けたい

#### インストールと初期ユーザー登録
Microsoft Storeアプリを立ち上げて`ubuntu`を検索し、導入したいバージョンを選択します。v24のLTS版が出ていたので、軽率にこれを選びました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/d0a28679-84d2-d981-89f0-ce720af8f7b7.png)

インストールのスピナーが停止し「開始」と表示されたら、これをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/339d6212-9c88-0bf0-744a-b8b8c1092559.png)

ターミナルが開いて、新しいユーザー名を入力するよう求められます。とりあえず`ubuntu`で登録しておきました。パスワードを設定して少し待ったら、緑文字のターミナル入力待ちになります。これで、Ubuntuのインストールは完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/d6b4735b-b118-98f2-9cec-621d591d5082.png)

## Docker Desktopをインストールする
### インストーラを入手する
[公式サイト](https://www.docker.com/ja-jp/products/docker-desktop/)で`Docker Desktopをダウンロードする`をクリックして、インストーラを入手します。アカウントの作成はしなくても進められます。

### インストーラを実行する
exeファイルをダブルクリックします。

最初の画面は1つ目のrecommendedされているものだけチェックが入っていればよいです。`OK`をクリックして、インストール処理が実行されるのを待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/aad5fdd0-84e6-8ec0-13f0-f4cff164e377.png)

インストールが成功したら`Close`をクリックしてインストーラを閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/a3ce1df3-68c5-aee0-b7ab-4de07c914fd9.png)

### Docker Desktopを起動する
インストールしたDocker DesktopをWindowsのアプリ一覧から起動します。プライバシーポリシー云々で同意画面が出るので、ちゃんと読んでから`Accept`をクリックします。

ユーザーの登録画面に遷移します。実は画面右上に`skip`が見えていますね。この後も2つほど、同様にアンケートっぽい画面が表示されますが、これも`Skip`できます。ナイショです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/10056b7a-ff54-ca1f-ad6d-ac3c020743dd.png)

### 設定値を変更する（Ubuntuを入れた人だけ）
画面上部の歯車マークから設定画面に遷移します。

使用するWSL2ディストリビューションとして、先ほどインストールしたubuntuを選択します。`Apply & Restart`をクリックして、関連リソースを再起動します。（けど、何も起こらなかったように見えた）

### UbuntuがWSL2のデフォルトディストリビューションになっていることを確認する（Ubuntuを入れた人だけ）
Docker Desktopインストールに際して独自のディストリビューションも導入されるので、このタイミングで確認します。管理者として実行したPowershellから、`wsl -l`を実行します。Ubuntuが既定となっていればOK。

## Visual Studio CodeからWSL2とDockerを利用する
拡張機能の`Remote Development`をインストールしておけば、一式使えるはず。

### WSL2に接続する
Ctrl + Shift + P でコマンドパレットを開いて、WSLに接続します。`WSL`と検索をかけるといくつか候補が出てきますが、ここまでの手順でUbuntuがデフォルトのディストリビューションになっているはずなので、シンプルに`WSL: Connect to WSL`を選んでおいてよいはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/e86e3f53-26a7-0a21-cd94-858e5bf27fd0.png)

画面左下部に`WSL: ディストリビューション名`が表示されたら、WSL2への接続が完了しています。ターミナルを開けば、ubuntuユーザーでログインしてコマンドの入力待ちになるはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/0cc56ad1-02eb-84b4-259f-50c5c15108a7.png)

### パッケージの最新化を行う
```bash
sudo apt update # パッケージ情報を更新
sudo apt upgrade # パッケージを更新
# 途中でDo you want to contiue? [Y/n]と聞かれたらyを入力
```

### Dockerが利用できるか確認する
以下2つのコマンドをWSL2のターミナル上で実行して、バージョン番号が返って来れば、WSL2とDocker Desktopを用いたコンテナ開発が可能になったと判断できます。

```bash
docker -v
# Docker version 27.2.0, build 3ab4256

docker-compose --version
# Docker Compose version v2.29.2-desktop.2
```

## WSL2やGit関連の設定を行う
必要に応じて、適宜以下の設定を行います。
* [【Docker】Remote-Developmentの構築](https://qiita.com/Shimooo_mutenka/items/2c28365a7ceb0ba32b31)
* [【Git】WSL2環境でGitを使う場合のGitHub SSHキー設定](https://qiita.com/Shimooo_mutenka/items/898bcf9891f47f05aca7)
    * Windows側の`C:\Users\<username>\.ssh`にGitの秘密鍵や設定ファイルがあるなら、WSL2側の `/home/ubuntu/.ssh/`（Ubuntuの場合）にファイルをコピーすればそのまま流用できます。この際、コンテナ内で`chmod 600 ~/.ssh/id_rsa`を実行し、ファイルのパーミッションを変更する必要があります。
* [【WSL2】Ubuntuディストリビューションのユーザーがsudoできるようにする](https://qiita.com/Shimooo_mutenka/items/cf7eaa79d5cb2562db05)

ここまでで、すべての手順が完了しました。あとは、コンテナで色々つくってこわして遊んでください！