Windows10 Home WSL2で Dockerを使う

## 著者の環境
- Windows10 Home
- WSL( ubuntu 18.04)
- CPU: core i-7
- RAM: 16GB
- Docker for windows

## はじめに
Windows 10 Proでは、Hyper-Vがデフォルト搭載されているため、Docker desktop for windowsを用いて簡単に環境構築できるが、Hyper-Vを兼ね備えていないWindows 10 Homeではdockerの構築に少し面倒である。

そこで、Windows 10 Homeの環境下で、dockerを使うにはいくつかの方法がある。
1. WSL(Windows Subsystem for Linux) を用いてdockerを立ち上げる
2. Vagrantを用いてVB上でdockerを立ち上げる

今回は、初期実行速度が速く、開発環境構築のステップが少ない、WSLを用いた1番の方法をsetupする。

# WSLを用いてdockerを立ち上げる
## 事前準備
1.  **WSL2をインストールする。**
Windows OS からubuntu 等のOSにアクセスできるように、WSL2をインストールする。 
WSL2のインストール手順については、ここでは省くが、WSL1ではなく、**WSL2** をインストールする。

2. **Docker desktop for Windows をインストールする**
Windowsマシンに、[Dokcer desktop for Windows](https://docs.docker.com/docker-for-windows/install/) をインストールする

3. **docker, docker-compose をインストールする**
WSL2のubuntuに、dockerとdocker-compose の最新版をインストールする。
参考資料：https://qiita.com/tettsu__/items/85c96850d187e4386c24

## 手順
### 1. WSL2の設定
なぜか、WSL2を用いたDocker desktop for Windowsでは、設定画面から、CPU等の割り当てを操作できないので、
ターミナル上から、CPU/メモリ/SWAP/ディスクサイズを変更しとく。


### 2. Docker desktop for windows の設定
やることは、WSL2上のdocker daemonを、Docker desktop for Windowsで使えるようにすることである。

<img width="1264" alt="image.png (100.4 kB)" src="https://img.esa.io/uploads/production/attachments/11134/2020/09/22/90339/f5b6f1d0-a93a-4ead-9b9b-896f9a6a18c1.png">
設定画面 > General にて、

  `Use the WSL2 based engine` を✔する

<img width="1189" alt="image.png (55.7 kB)" src="https://img.esa.io/uploads/production/attachments/11134/2020/09/22/90339/d4a807c7-2598-4288-b3e0-f3fb4bd994f0.png">
設定画面 > Resources > WSL INTEGRATION で、

`Enable integration with my default WSL distro` を✔する。

WSL2上にubuntuがインストールされ、正しく設定できていれば、上記の写真のように、「Ubuntu」みたいな表示が出てくるので、Onにする。

**[メモ]**
もし、上記の✔欄がチェック出来ないようになっていたら、

- tcp://localhost:2375 の設定が出来てない。(localhostのパスを、bashrcにexportし忘れ)
- WSL2ではなく、WSL1を使用している

などの原因が考えられる。(詳しくはググってください)


### 3. WSL2上のubuntuターミナルに、プロジェクトを作成する。

WSL2上のubuntuターミナル(以下、ubuntuターミナルと呼ぶ)に、プロジェクトを作成していく。

```bash
ubuntu:~ $ mkdir work
ubuntu:~ $ cd work
ubuntu:~/work $ git clone git@github.com/~
```

**[注意すべき点]**

- 一般的に、`/mnt/c`　を用いて、 ubuntuターミナルからWindowsディレクトリにアクセスできるが、
今回は、Windowsディレクトリ上にプロジェクトを作成し、ubuntuターミナルから参照するのではなく、**直接ubuntu上のディレクトリにプロジェクトを作成する。**
(Windowsディレクトリ上のプロジェクトでdockerを立ち上げた場合、ディスクアクセスに物凄く時間がかかり、docker立ち上げから初期画面表示までに5minくらいかかる。筆者はここで躓いた。。)

### 3. docker-compose up していく
ubuntuターミナルを開き、dockerコンテナを立ち上げていく。

```
$ docker-compose up -d
```

これで、エラーが吐かれずに、コンテナを立ち上げればokだが、
筆者の環境ではそんな簡単にいかなかったので、筆者が直面したエラーとその解決策を下記に記しておく。

## 環境構築におけるエラーとその解決策
### case 1:  shファイルが見当たらん！
**エラー**

```
ERROR: for rails_1  Cannot start service rails: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"bin/start_dev_server.sh\": stat bin/start_dev_server.sh: no such file or directory": unknown
```
**発生手順**
1. `/mnt/c` 以下にプロジェクトを作成
2.  `docker-compose up`

**原因**
この場合、WSL2の絶対パスのルートは、`/mnt/c` であるが、
Docker for WindowsのVMでは、 `/C` の絶対パスのルートが適用されるためであった。

**解決策**
Windowsディレクトリ下にプロジェクトを作成し参照するのをやめ、ubuntuディレクトリ下にプロジェクトを作成しましょう。

**参考リンク**
- https://github.com/microsoft/WSL/issues/1854#

### case 2: AWS S3にアクセスできん！
**エラー**

```
Aws::S3::Errors::RequestTimeTooSkewed: The difference between the request time and the current time is too large.
```

**発生手順**
1. `docker-compose up`
2. AWS S3からマスク済データをfetchしてくるときにエラー

**原因**
WSL2(ubuntu ターミナル)で動くDockerコンテナの時刻が大幅にずれているのが原因だった

Windows ホスト側(正)

```
$ data 
Sun Aug 30 18:16:29 JST 2020
```

ubuntuターミナル側

```
$ data
Sun Aug 28 11:16:29 JST 2020
```

**解決策**
1. 初めに、`Aws::S3::Errors::RequestTimeTooSkewed` のエラーはTimezoneが違う場合でも発生するので、docker-compose.yml 内でtimezone をJSTに設定しとく。

```docker-compose.yml
services:
  web: 
   environment:
     TZ: Asia/Tokyo
```

2. 次に、
まず、コンテナのシェル内でdataコマンドを使うときに、 operation not permitted にならないように、権限設定をしとく必要がある。


```docker-compose.yml
services:
  web:
   privileged: true
```

3. 最後に、
コンテナのシェル内で、`data` コマンドを使って日付を変更する

```bash
$ data --set "2020-08-30 18:16:29" //現在時刻に手動で設定
```

**メモ**
他にも、 `hwclock -s` を用いて無理やり時間を変えられるらしいが、下記のエラーで死す。

```bash
$ hwclock -s
hwclock: Cannot access the Hardware Clock via any known method.
```

**参考リンク**
- https://qiita.com/sadakan5/items/4c0a394fd1d6be34efb2

### case 3: docker-daemonがコネクトされてない！
**エラー**

```
$ docker-compose up
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.
```

**発生手順**
1. `docker-compose up`

**原因**
筆者が把握している原因としては、

1. VMを他に起動している
(ここが非常に厄介なのだが、) Hyper-V プラットフォーム(<- Hyper-Vとは別物)で動く、dockerを使用する際に使われてる仮想マシンプラットフォームと、Oracle Virual Boxなどの他の仮想マシンを同時に使うことは、Hyper-V プラットフォームの競合が起きるのであんまよろしくないらしい(?)。
- 参考リンク: https://qiita.com/matarillo/items/ca1eecf8f9a3cd76f9ce

2. WSLが有効になってない

おそらく他にも色々原因はあると思います。

**解決策**
For 原因1 
- 他のVMをstop する
- 再起動

For 原因2

- PowerShell を開いて、

```PowerShell
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```
参考リンク: https://qiita.com/aki4000/items/c26e3076c8cec9677415


# その他
## 初期画面表示までにかかる時間(憶測)
- Opt 1 [WSL2] : 今回紹介した、WSL2を用いてubuntuディレクトリ下のプロジェクトのdockerを立ち上げた場合

- Opt 2 [WSL2 in `/mnt/c`project]: 
上で少し紹介したが、WSL2を用いてWindowsディレクトリ下のプロジェクトのdockerを立ち上げた場合

- Opt 3 [Vagrant]: Vagrantを用いて、VM上にdockerを立ち上げた場合

**dockerコンテナ立ち上げ後、localhostへアクセスしてからトップページが表示されるまでの時間 ⇓**

| Opt 1[WSL2] | Opt 2[WSL2 in `/mnt/c`project] | Opt 3[Vagrant] |
| -------- | -------- | -------- |
|  15 s   |  5 min     | 3 min     |

## ubuntuディレ下のプロジェクトをRubyMine等のIDEで編集したい
Windows ディレ下にあるプロジェクトの場合、普通にRubyMineやVS codeを開いて編集すれば良いが、
Windowsターミナルからubuntuディレを見るのは少々面倒で、ubuntuディレ下のプロジェクトをIDEを用いて編集するのは、若干ややこしい。

### 手順
1. [Vcxsrv](https://sourceforge.net/projects/vcxsrv/) をインストールし、よしなに設定する
2. ubuntuターミナルから、Rubymineをインストールする
3. Vcxsrvで得られたXlaunchを起動し、rubymine.shを起動する