WSL2 + VScodeでWindowsから一瞬でDockerコンテナ内に引き篭もれる開発環境を整えたかった

# WSLとは？
めっちゃ簡単に言えば、Windows10内に手軽にLinux環境を作れるようになる。
現在正式リリース中のWSLではDockerが動かなかったが、プレビュー版公開中のWSL2からはそれが解消され、話題になっている。
# この記事で目指したかったこと
 * Windows立ち上げてvscode開くだけでDockerコンテナ内の開発ソースディレクトリを開けるようにする
       * 結果的に、完全には引き篭もれなかったが、WSL2の良さは実感できた。また、今後のバージョンアップを待てば無事完全に引き篭もれる見込み。
       * **(2019/03/08追加)引き籠もれるようになりました。**
          * https://www.docker.com/blog/docker-desktop-for-windows-home-is-here/

# WSL2 + VScode + Dockerによる開発環境構築
## WSL2環境構築
### Windows Insider Preview登録
2019年8月現在WSL2は正式リリースされておらず、Windows Insider Previewに登録しなければ入手できない。
なので、登録していない人は以下のページ参考に登録から始める必要がある。
[Windows Insider Program ユーザー ガイド](https://insider.windows.com/ja-jp/how-to-pc/)　
ファストとスローの2種類あるが、WSL2はファストでないと入ってこないので注意。
なお、はじめは更新完了まで数時間かかる。
私は休日の昼間に初めて結局その日はまともにWSL2を触れなかった。寝る前にやるべし。
*注 Windows Insider Previewは正式リリース前の不安定なプログラムがWSL2以外にもどんどこ入ってくるため、大事なデータの入っているPCではやらないほうが良い。
### WSLのインストール
Insider Preview導入による再起動の嵐が無事終わったら、WSLが入っていない人は以下の記事を参考に導入する。
（WSL2直接インストールはできないっぽい？）
[Windows 10 用 windows Subsystem for Linux インストールガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)
### WSL1 →　WSL2への変換
PowerShellを管理者権限で起動後、以下のコマンドで仮想マシンを有効化する。

```
PS C:\WINDOWS\system32> Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```
再起動がかかるので、完了したら再度PowerShellで以下のコマンドでwslが入っているか確認。

```
PS C:\WINDOWS\system32> wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         1
```
Ubuntuが表示されたら正常に導入されている。続けて次のコマンドでWSL2への変換とWSL2を既定にする。

```
PS C:\WINDOWS\system32> wsl --set-version Ubuntu 2
PS C:\WINDOWS\system32> wsl --set-default-version 2
```
WSL2になったか確認。VERSIONが2になっていたらOK

```
PS C:\WINDOWS\system32> wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         2
```
これによりWSL2が以下のコマンドで起動できるようになる。
PowerShellじゃなくてもWindowsのコマンド実行できるならどのターミナルでもOK。
起動するとSSHみたいにそのままLinuxに入るので、お気に入りのターミナルで。

```

# この起動方法だと、wsl起動後のパスがWindowsのコマンド実行時の場所をそのまま引き継ぐ
PS C:\WINDOWS\system32> wsl
user@hoge:/mnt/c/Windows/System32$

# こっちだとホームディレクトリで起動する。わかりやすいのでこっちがオススメ
PS C:\WINDOWS\system32> ubuntu
user@hoge:~$
```
やってみればわかるが、ほとんど一瞬で起動するので驚いた。
Virtual Boxとかだと環境によって起動で数分待たされることがあるが、WSLは数秒かかるかどうかで凄く早い。
## WindowsのVSCodeでWSL2にリモートアクセスする。
2019年8月現在、Windows Home版はこのやり方しかない模様。
完全にはコンテナに引き籠もれないが、WSL2の快適さの恩恵は得られる。
### パッケージの更新、Git、Docker、Docker-composeインストール
ほぼ完全なUbuntu環境なので、この辺は通常のLinuxと同様に進めれば良い。
[最新版の Git をインストールする - Qiita](https://qiita.com/noraworld/items/8546c44d1ec6d739493f)
[Ubuntu に docker と docker-compose を入れる - Qiita](https://qiita.com/mochizukikotaro/items/ae7ae1461ea4bf495bd0)
### Dockerで起動したサービスにWindowsからアクセス
Windowsを主軸に開発環境を構築するので、WindowsからWSL2内のDockerコンテナへアクセスできなければ意味がない。
ポートフォワーディングとかややこしい設定しないといけないのかなと思ったが、なんの心配もいらなかった。普通のLinux環境と同じようにDockerコンテナを起動するだけで良い。
例えば、PHP + Apache環境のコンテナへHTTP接続を試してみる。

```shell
# 公式イメージでコンテナ起動
$ sudo docker run -d --name sample-apache-php -p 80:80 -v "$PWD":/var/www/html php:7.2-apache
# PHPの設定情報を出力するphp作成
$ vi index.php
```
```php:index.php
<?php phpinfo(); ?>
```
Windowsのブラウザからlocalhost:80へアクセスすると、PHPの設定情報画面が表示される。
なお、初期のWSL2ではこのlocalhost接続がうまくできなかったが、すぐにアップデートで対応された。
[「WSL 2」最大の課題であった“localhost”問題が解決 ～「Windows 10」Build 18945 - 窓の杜](https://forest.watch.impress.co.jp/docs/news/1198651.html)
### Windowsで起動したVSCodeからWSL2へリモートアクセスし、編集できるようにする
Windowsからサービスへのアクセスを確立できたところで、次はWSL2内のDockerコンテナにマウントしたソースファイルを編集して、開発を進めるための環境を整える。
WSL2とVSCodeは共にMicrosoft製なだけあって、簡単に連携ができる。
VSCodeで以下の拡張機能を導入する。
[Remote Development - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
インストールすると、VSCodeの左下に「><」といった感じのボタンが追加されるので、それをクリックすると画面上部に何処へ接続するか等の候補が表示される。
![VScode Remote.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252649/eae65df5-8687-924b-5b21-c5e79b94b195.png)
「Remote-WSL: New Window」をクリックすると、（初回起動時は時間がかかるが）WSL2へアクセスした状態のウィンドウが新しく開く。
「フォルダを開く」ボタンをクリックすると、どのパスを開くか聞かれるので、プロジェクトのルートディレクトリを指定すれば、無事WSL2内のソースファイルを編集できるようになる。
「Remote Development」拡張は他にもSSH接続でサーバのソースファイルを直接いじったりできる便利ツールなのだが、その場合は当然鍵認証やパスワード認証が必要になる。
しかし、WSL向けの接続の場合、そういった認証は一切いらない。鍵の準備もいらない。クリックするだけで良い。同一PC内なので当然なのだが、VMと比べてこの辺の融通の利き具合が心地良い。
### この方法の問題点
無事、Windows内に起動から数クリックで起動できる手軽なLinux開発環境を構築し、サービスへのアクセスや開発環境も通常のLinux環境と差異のないものが手に入ったが、まだ問題がある。
**この方法ではコンテナに完全に引き籠もれない。**
あくまで、コンテナにマウントするWSL2上のディレクトリを編集しているだけである。VSCodeはコンテナではなくWSL上で動いている。
そのため、例えばESLint拡張をVSCode上で動かそうとする場合、VSCodeが動いている環境にNode.jsが必要となるため、コンテナだけでなくWSLにもNode.jsを入れなければいけなくなる。完全な二重管理状態だ。
ホストを無用に汚す必要がなくなるというコンテナの利点の一つを殺すことになり、大変よろしくない。
折角コンテナを活用するのなら、そのコンテナ内に引き籠もりたい。Node.jsでの開発をするのなら、Node.jsのことだけを考えていたい。プログラミングでもインフラでも、要素感の疎結合性は重要だ。外部への依存は必要最低限にしたい。
## 完全にコンテナに引き篭もる方法
**※以下の問題はその後のDocker Desktopアップデートで解決済**
VSCodeのRemote Development拡張は、WindowsからWSL2まではアクセスできても、更にWSL2からコンテナのアクセスや別の環境へSSH接続することはできない。
しかし、WindowsからDockerコンテナへのアクセスはサポートされている。
そこで出番になってくるのがWindows上でDockerを動かす「Docker Desktop」。
これまで、安定性や動作の重さに難があったそうだが、今回WSL2を正式サポートすることでその辺の問題の解消が期待されている。
現在、こちらもWSL2に対応したプレビュー版を公開しており、公式ブログでも以下のようにWindowsのVSCodeからDockerコンテナへのリモートアクセス対応を記載している。
[5 Things to Try with Docker Desktop WSL 2 Tech Preview - Docker Blog](https://blog.docker.com/2019/07/5-things-docker-desktop-wsl2-tech-preview/)
> 4.Visual Studio remote with WSL
You can work natively with Docker and Linux from Visual Studio Code on Windows.

で、早速私もプレビュー版を導入してみようとしたのだが、どうもWindows Homeだとインストールが途中で進まなくなる不具合が発生しており、導入ができなかった・・・。なお、これまでと違いHyper-VでなくWSL2を使うので、Homeでも動くようになるよというのは、[こちらの記事](https://engineering.docker.com/2019/06/docker-hearts-wsl-2/)で言っている
この不具合ついて、Docker側のコメントが見つからなかったが、Microsoftの人が以下のようにブログでコメントしているのが見つかった。
[Run Linux Containers with Docker Desktop and WSL 2 - Thomas Maurer](https://www.thomasmaurer.ch/2019/08/run-linux-containers-with-docker-desktop-and-wsl-2/)
>I think this is currently because of the installer still check for that version.  My guess is that with newer versions of the preview it will go away. However, I will try to find out :)

「おそらく次のバージョンで直るよ」

# 結論
Windows Homeから一瞬でDockerコンテナに完全に引き篭もれるようになるには、まだしばらく時間が必要なようだ。

# 参考
Qiita上でDocker Desktop for WSL2を実際に入れて、詳細な機能の解説を書かれている記事があります。
[Docker Desktop for WSL 2 を入れてみました - Qiita](https://qiita.com/SHIRANO/items/42616bb76630df068f33)

# 余談
はじめてQiitaに記事を書いた。
アウトプットすることで知識が整理されるというのは聞いていたが、確かに効果がある気がする。
今後も何かあったら書いていきたい。
あと、本当はこのWSL2 + Docker + VSCodeで具体的に何が嬉しくなるのかについて、自分の認識を書きたかったが、途中で力尽きたのでこれで終わりにする。また別の機会に。
間違っているところかありましたら、ご指摘をよろしくお願いいたします。

# 追記(2020/03/08)
Windows Home対応のDocker Desktopが来ました。
https://www.docker.com/blog/docker-desktop-for-windows-home-is-here/