VSCodeの拡張機能DockerをVagrantで作成したDocker環境にも適応させる

# はじめに
Dockerを使用していると、イメージに何がある？コンテナ何が立ってるっけ？など起きてくると思います。
Dockerコマンドで

```bash:command
docker image ls
docker container ls
```
と打って確認するのも素早い手ですが、GUIでいつでも見れたら嬉しいですよね？
今回はDockerという拡張機能を使用し、VSCodeで現在使用しているイメージ、コンテナ、レジストリを確認できるようにしたいと思います！

# 前提
VagrantでDocker環境を作成する方法は次の記事で紹介しております。

- [Vagrant+Dockerでスマホからでも見れるWEB環境を手に入れる](https://qiita.com/mokusen/items/852927f01683362a5787)

今回の記事は、VSCodeの拡張機能Dockerに適応させることが目的なので、新たに何か出来ることが増えるわけではございません。

# 注意事項
今回紹介するのはローカル環境で使用することを前提として、提案しています。
本番環境のDocker環境として使用することは推奨しません。

# 行うこと
- 忙しい人は、[忙しい人向け](#忙しい人向け行うこと)へ進みましょう。
- Vagrantで作成したDocker環境が無い方は[下準備](#下準備)を行いましょう。
- すでに持っている方は[本題](#本題)へ進みましょう。

## 下準備編
1. [すでに環境を持っている人](#下準備-1-すでに環境を持っている人)
2. [環境を持っていない人](#下準備-2-環境を持っていない人)

## 本題編
1. [Docker daemonを全てのIPから接続可能にする](#本題-1-docker-daemonを全てのipから接続可能にする)
2. [ゲストPCでDockerコマンドを打てるようにする](#本題-2-ゲストpcでdockerコマンドを打てるようにする)
3. [ホストPCからゲストPCに対してDockerコマンドが叩く方法](#本題-3-ホストpcからゲストpcに対してdockerコマンドが叩く方法)

# 忙しい人向け：行うこと
原理なんてどうでもいい！実行したい！という人向け。
[既存のVagrantfile](https://github.com/mokusen/qiita-vagrant-docker/blob/master/vagrant-finish/Vagrantfile)に以下の設定を追加する。

```rb:Vagrantfile
config.vm.network "forwarded_port", guest: 2375, host: 2375, host_ip: "127.0.0.1"
```

```rb:Vagrantfile
config.vm.provision "shell", inline: <<-SHELL
    chmod +x /usr/local/bin/docker-compose

    # この間に下記を追加

    find /usr/lib/systemd/system/docker.service -type f -print | xargs sed -i -e "s*ExecStart=/usr/bin/dockerd*ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375*g"
    echo export DOCKER_HOST=tcp://127.0.0.1:2375 >> .bashrc

    # この間に上記を追加

    systemctl start docker
    systemctl enable docker
SHELL
```

既存のVagrant環境を破棄する。

```bash:command
vagrant destroy
```
再度、Vagrant環境を作成する。

```bash:command
vagrant up
```

次のコマンドを打ち、Hello-worldコンテナを追加する。

```bash:command
vagrant ssh -- docker run --name hello hello-world
```

VSCodeのGUIで確認する
![vscode-docker.PNG](https://qiita-image-store.s3.amazonaws.com/0/262838/0b025a36-d93a-ea5d-f29a-73356687825c.png)

確認できたら、Hello-worldコンテナは邪魔なので削除して終了。
コマンドから

```bash:command
vagrant ssh -- docker rm hello
vagrant ssh -- docker rmi hello-world
```
GUIから

- imagesのHello-world上で右クリックし、Remove Imageを選択
- Containerのhello上で右クリックし、Remove Containerを選択

以上です。

# 利用環境
ホストPC：現在使用しているPCのことです。
ゲストPC：VirtualBoxで作成する仮想マシンのことです。

## ホストPC
| Type | Version |
|:--- | :--- |
| Windows10 | Home |
| VSCode | 1.28.2 |
| 拡張機能：Docker | 0.3.1 |
| Vagrant | 2.1.5 |
| VirtualBox | 5.2.18 |
| Vagrant Box | bento/centos-7 |

## ゲストPC
| Type | Version |
|:--- | :--- |
| CentOS | 7.5 |
| Docker-Engine | 18.06.1-ce |
| Docker-compose | 1.23.0-rc3 |

# 目的物
![vscode-docker.PNG](https://qiita-image-store.s3.amazonaws.com/0/262838/0b025a36-d93a-ea5d-f29a-73356687825c.png)

上記の画像のように確認できるようにすることが今回の目的です。

# 拡張機能：Docker
この拡張機能は以下のことが出来ます。
そのため、追加して使いたい。
## 出来ること
- Dockerイメージのbuild push
- Dockerコンテナの削除
- Docker-Compose up down
- Dockerfileのシンタックスハイライト
- docker-compose.ymlのシンタックスハイライト
- Dockerイメージ、コンテナ、レジストリの閲覧
- etc...

## 本環境で出来ること
- Dockerコンテナの削除
- Dockerfileのシンタックスハイライト
- docker-compose.ymlのシンタックスハイライト
- Dockerイメージ、コンテナ、レジストリの閲覧

ホストPCにdockerが入っていることを前提にこの拡張機能は作成されている影響で、本環境の場合、フルに活用することは出来ない。

# 下準備
## 下準備 1. すでに環境を持っている人
環境を持っている場合は一度、Vagrant環境を削除する必要があります。
バックアップを取るなどして対応しましょう。

```bash:command
vagrant destroy
```

## 下準備 2. 環境を持っていない人
こちらでは、事前に準備した[Vagrantfile](https://github.com/mokusen/qiita-vagrant-docker/blob/master/vagrant-finish/Vagrantfile)を使用します。
VirtualBox、Vagrantの設定については、

- [Vagrant+Dockerでスマホからでも見れるWEB環境を手に入れる](https://qiita.com/mokusen/items/852927f01683362a5787)

を参照して頂けると、設定することが出来ます。

# 本題
この工程が終わると以下の環境が手に入ります。

- ホストPCからvagrant sshを利用してDockerコマンドが打てるようになる
- ホストPCのVSCodeでDockerイメージ、コンテナ、レジストリの情報を見れるようになる

## 本題 1. Docker daemonを全てのIPから接続可能にする
ここではホストPCのVagrantfileを操作します。
Dockerのdaemonを全てのIPから接続可能とするためにPortを開放します。

```rb:Vagrantfile
config.vm.network "forwarded_port", guest: 2375, host: 2375, host_ip: "127.0.0.1"
```
※ port:2375を開放する理由は公式より、例として使用されているから。何番でも構わない。
※ ただし、port番号を変えた場合、以降登場する2375は全て、ここで変えたport番号を使用して下さい。

次のコマンドを

```bash:command
find /usr/lib/systemd/system/docker.service -type f -print | xargs sed -i -e "s*ExecStart=/usr/bin/dockerd*ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375*g"
```
下記の間に追加しましょう。

```rb:Vagrantfile
config.vm.provision "shell", inline: <<-SHELL
    chmod +x /usr/local/bin/docker-compose

    # ここに追加する

    systemctl start docker
    systemctl enable docker
SHELL
```
※ ここで追加したコードはdocker.serviceを検索し、ファイル内容を置換する。という処理をしています。
※ 個人的に良い書き方とは思っていないので、いい案がある方は教えて頂けると幸いです。
※ 気になった方は`linux 検索`や`linux 置換`などを調べてみると良いです。

## 本題 2. ゲストPCでDockerコマンドを打てるようにする
本題1を行っただけでは、スムーズにDockerコマンドが打てるようにはなっていません。
試しにVagrantにログインして、Dockerのバージョンを確認してみましょう。

```bash:command
PS C:\Users\YourName\vagrant-project> vagrant up
PS C:\Users\YourName\vagrant-project> vagrant ssh
[vagrant@localhost ~]$ docker info
```
そうすると、以下のようにエラーが発生すると思います。

```shell-session:エラー内容
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

これは先程Dockerの起動方法を変更しているため、次のように打たないとDockerは反応しません。

```bash:command
[vagrant@localhost ~]$ docker -H 127.0.0.1:2375 info
```
...-H 127.0.0.1:2375を付けるの面倒くさいので、環境変数として設定します。
次のように設定しましょう。

```bash:command
[vagrant@localhost ~]$ export DOCKER_HOST=tcp://127.0.0.1:2375
```
ただ、これだとVagrantからログアウトすると、DOCKER_HOSTの設定は消えてしまいます。
そのため、環境変数の記入先である.bashrcに上記の内容を記述します。
確認のため、以下のコマンドを実施し、手順に従って行いましょう。

.bashrcの確認

```bash:command
[vagrant@localhost ~]$ ls -a
# 上記のコマンドを実施し、.bashrcがあればOK。ない場合は下記の操作を行う。

[vagrant@localhost ~]$ cd ~
```

.bashrcに追記する

```bash:command
[vagrant@localhost ~]$ echo export DOCKER_HOST=tcp://127.0.0.1:2375 >> .bashrc
```
この設定をVagrantでDocker環境を作成する時に行ってほしいので
Vagrantfileに追記します。

```rb:Vagrantfile
config.vm.provision "shell", inline: <<-SHELL
    chmod +x /usr/local/bin/docker-compose
    find /usr/lib/systemd/system/docker.service -type f -print | xargs sed -i -e "s*ExecStart=/usr/bin/dockerd*ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375*g"

    # ここに追加する
    echo export DOCKER_HOST=tcp://127.0.0.1:2375 >> .bashrc

    systemctl start docker
    systemctl enable docker
SHELL
```

追記をしたら、Vagrantを再設定する必要があるため、一度Vagrant環境を廃棄し、再度作成します。

```bash:command
PS C:\Users\YourName\vagrant-project> vagrant destroy
PS C:\Users\YourName\vagrant-project> vagrant up
```

## 本題 3. ホストPCからゲストPCに対してDockerコマンドが叩く方法
これはほとんど補助的な役割です。
なぜならコマンドの実行が遅いからです。
`vagrant ssh`してからdockerコマンドを実行する場合と、これから試す方法では実行時間に5秒ほど時間がかかります(環境によって差が生じます)。この時間は`vagrant ssh`を実行する時間分です。
それを考慮の上使用してください。

### hello-worldコンテナを作成する
vagrantはsshのあとに`--`を追加することでコマンドを実行させることが出来ます。
そのため、以下のコードでhello-worldコンテナが作成可能です。

```bash:command
vagrant ssh -- docker run --name hello hello-world
```
VSCodeのGUIで確認する
![vscode-docker.PNG](https://qiita-image-store.s3.amazonaws.com/0/262838/0b025a36-d93a-ea5d-f29a-73356687825c.png)

確認できたら、Hello-worldコンテナは邪魔なので削除して終了。
コマンドから

```bash:command
vagrant ssh -- docker rm hello
vagrant ssh -- docker rmi hello-world
```
GUIから

- imagesのHello-world上で右クリックし、Remove Imageを選択
- Containerのhello上で右クリックし、Remove Containerを選択

これで完了です！
お疲れ様でした！