windows 10 Home 64bit でdockerを動かす話

# windows 10 Home 64bit でdockerを動かす話

過去にメモしたものを発見したため、一応上げとくことにしました。もう結構前のメモで忘れていること多いため、何か間違いあったら教えてください。もう自分はProにしましたが、Win10でHomeのままでどうしてもDockerやるしかないというレアな場合の人は、参考にしてみてください。Proの場合は、普通にdocker for windows 使ってくれ。

## 導入準備編
[windows 10 home で docker を導入するメモ](https://qiita.com/idani/items/fb7681d79eeb48c05144)を参考にします。

Homeの場合には、[docker tool box](https://docs.docker.com/toolbox/overview/)が必要なよう。

インストール時のチェックボックスは全て入れる。（ここで、gitを入れなくてエラー、一番下のチェックボックス「Install VirtualBox with NDIS5 driver[default NDIS6]」を入れなくてエラーとなった）

それらを行えば、普通にインストールできる場合もあるが、自分の環境では

```
This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory
```

と怒られた。

ので、BIOSの設定もする必要があった。

[Windows 上から 「 BIOS 設定 」 画面を表示する方法 ( Windows10 )](https://www2.mouse-jp.co.jp/ssl/user_support2/sc_faq_documents.asp?FaqID=21649)を参考に、BIOSの設定を進める。

この際、再起動後に自分の環境では、F10を選択してBIOS設定画面に行く必要があった。設定画面の、「System Configuration」=> 「Virtualization Technology」を選択、enabledにする。

そして、再度docker tool box インストールツールを開き、再インストール。この際、自分は元あったやつ消さなかったが上手くいった。

再インストールしたら、docker quick start terminalを開く。コンソール上で勝手にやってくれる。（適宜、enterキーを押す必要がある。何も進まないなぁ思っても、押したら進むことがある。なにこれ。

完了したら、クジラの絵が見える！

ここまできたら、あと少し。今度はwsl側で、[dockerに必要なものを入れ](https://qiita.com/yanoshi/items/dcecbf117d9cbd14af87#管理者権限で動いているwslからdockerをインストール)、[windowsにあるdocker daemonにwslからアクセスするよう環境変数を設定](https://laboradian.com/use-docker-toolbox-with-wsl/#3_WSL_docker_daemon)して、完了。

環境変数は、直接コマンドラインから入力してもいいが、それだと毎回入力することになる。wslでbashを起動する際に自動的に入れるようにしたほうが楽。

```
> C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs
```

以上が、wslのホームディレクトリとなる。あとは、自身の環境に応じた場所に書き込む。

自分の場合は、

```
> C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\home\%ACCOUNT_NAME
```

内の".bash_profile"に以下を追記して反映できた。

```
export DOCKER_HOST=tcp://192.168.99.100:2376
export DOCKER_CERT_PATH=/mnt/c/Users/{あなたのユーザー名}/.docker/machine/certs
export DOCKER_TLS_VERIFY=1
```

あとは、いろいろインストールして実行するだけ！

```
sudo apt install docker.io
sudo cgroupfs-mount
sudo usermod -aG docker $USER
sudo service docker start
export DOCKER_CERT_PATH=/mnt/c/Users/{あなたのユーザー名}/.docker/machine/certs
export DOCKER_HOST=tcp://192.168.99.100:2376
export DOCKER_TLS_VERIFY=1

docker run hello-world
// "Hello from Docker!"が見えるはず！
docker images
// REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
// hello-world         latest              fce289e99eb9        4 weeks ago         1.84kB
```

### docker-composeまで動かす

```
sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose
// sudo apt install docker-compose だと古いものがインストールされてしまうので、ダメ
// 間違えて apt install で入れてしまった場合は、`sudo apt remove docker-compose`する
sudo chmod a+rx /usr/local/bin/docker-compose
docker-compose --version

sudo curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
```

## 実際にnuxtアプリ作ってみる編

以下では、Dockerコンテナの中でNuxtアプリをNode.jsサーバー上で動かしてみる。
Dockerfileで行う場合と、docker-composeで行う場合の２パターンを用意した。

リポジトリは[こちら](https://github.com/Mizumaki/Nuxt_Docker_sample)。

**注意点: また、docker toolboxがvirtual boxに依存している以上、そちらの設定も行う必要が多いことを認識しておく。**

### VirtualBoxでの事前準備

- 共有ファイルの設定

docker-toolboxを使う場合、基本的にDockerはVirtualBox上のゲストOSと通信することになる。

つまり、「Dockerコンテナ上のOS => VM上のOS => ホストPCのOS」となる。

そのため、DockerからVMへの「共有ファイルの設定（つまりVolume）」「ポートフォワーディングの設定（つまり`-p`オプション）」のほかに、VMからホストPCへの「共有ファイルの設定」「ポートフォワーディングの設定」も行う必要がある。

といっても、こちらの[「VirtualBox上のLinuxとフォルダを共有する」](http://pineplanter.moo.jp/non-it-salaryman/2016/10/19/virtualbox-share-folder/)や、こちらの[「ポートフォワーディングの設定」](https://www.karakaram.com/virtualbox-port-fowarding#port-forward)などを参考にすればすぐ終わる。

VirtualBoxとローカル間のフォルダ共有が完了したら、VirtualBoxのコンソールに入って（「キャプチャ」とかいうらしい）、`ls`などを使ってフォルダの場所を確認しておく。そこまで終わってから、Dockerに進む。

### Dockerfileでやる

[サンプルにあるdockerfile](https://github.com/Mizumaki/Nuxt_Docker_sample/blob/master/dockerfiles/nuxt.Dockerfile)を用意。

```
docker build -t gketest -f ./dockerfiles/nuxt.Dockerfile ./dockerfiles
// -t オプションでimageのREPOSITORYネームを指定する
// -f オプションは、Dockerfileという名前でないファイルをDockerfileとして使用したい場合に使用する

docker run --name nuxt -it -p 80:3000 -v /development/gketest/nuxt:/nuxt gketest
```

-p では、 vmのポート:コンテナのポートとなる。

`docker run -ti {ビルドで生成されるイメージID} bash`でbashに入って、`# hostname -i`を実行すると、そのDockerコンテナ内のlocalhostのIPアドレスがわかる。

そのhostアドレス上で`yarn dev`を走らせる必要がある。localhostは内部を指してしまうため、内部で閉じてしまう。

[-itオプション](https://teratail.com/questions/19477)を付けるのを忘れると、以下のエラーがでることがあります。

```
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"-name\": executable file
not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled
```

以上のようにやれば、volumeオプションによりコンテナ上にもホストOSのファイルをマウントされているはずであるが、変更が検知されなかった。恐らくだが、この理由はキャッシュ周りではないかと思われる。VM側からファイルを読んでみたところ、変更は反映されていたので、コンテナ内で変更がキャッチできていないものと思われる。

一旦、ctrl + C でストップさせ、再度`docker start nuxt && docker attach nuxt`で、再度ビルドしたら変更が反映されていた。

これだとやっかいなので、なんとかしたいと思って調べたら[解決策](https://github.com/nuxt/nuxt.js/issues/2481)を見つけた。

どうやら、nuxt.config.jsに以下のオプションを追記すれば良いようである。

```nuxt.config.js
watchers: {
  webpack: {
    poll: true
  }
}
```

### docker-composeでやる

```
docker-compose build
// まぁまぁ時間かかる
docker-compose up -d
docker-compose exec web bash

create-nuxt-app test
cd test
npm install
```

### nuxtアプリをdocker上で起動する

```
docker build -t nuxt .
docker run nuxt -p 8080:3000 nuxt
```

失敗しても、`docker run -ti {ビルドで生成されるイメージID} bash`で入れる。入って出るのは`exit`。


# 遭遇したエラー

```
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded
while awaiting headers).
```

この場合は、docker-toolboxをrestartする
https://docs.docker.com/machine/reference/restart/

```
// docker-toolbox のコマンドラインより
$ docker-machine restart default
Restarting "default"...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
Waiting for SSH to be available...
Detecting the provisioner...
Restarted machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
```

yarn install時のエラー。
VM上で実行すると起こりやすいよう。
`--no-bin-links`オプションを付けることが公式の解決策になっている、今のところ
https://github.com/yarnpkg/yarn/issues/2983
https://github.com/yarnpkg/yarn/issues/929

```
error An unexpected error occurred: "EROFS: read-only file system, symlink '../../../parser/bin/babel-parser.js' -> '/nuxt/node_modules/@babel/core/node_modules/.bin/parser'".
```

CMD bash -c "yarn install --no-bin-links && yarn dev"
これがいけなかった。
bashで直接`nuxt`が実行されてしまっていたため、globalに存在しないからエラーとなっていた。

```
# yarn dev
yarn run v1.13.0
$ nuxt
/bin/sh: 1: nuxt: not found
error Command failed with exit code 127.
```

# 参考
https://qiita.com/yanoshi/items/dcecbf117d9cbd14af87
https://qiita.com/tettsu__/items/85c96850d187e4386c24
https://qiita.com/osuo/items/99a2b7413ce75f8217be

エラー対策
https://qiita.com/yaju/items/0e98e88f3638d25d69e0
https://teratail.com/questions/124097
https://qiita.com/rema424/items/9306e96307d0814dc57b

chocoの話 (brew cask)
https://www.shibuya24.info/entry/chocolatery

gke
https://www.topgate.co.jp/gcp07-how-to-start-docker-image-gke