Vagrant+Dockerでスマホからでも見れるWEB環境を手に入れる

# はじめに
WEBサイト、アプリを作成している時に、スマホ端末からWEBサイト、アプリを確認したい...
と思う、個人開発者はいるかなーと思い、書いています。
そのため、あまりネットワークなどの技術については関与しません(私も詳しくない)。

この記事でDockerを使用するメリットは無いですが、趣味と今後のことを考えて使います。

# 前提
なんでDocker Toolbox使わないのー？
→Vagrantを使いたかった、ただその一心です。

# 行うこと
Vagrantのやり方がある程度分かる人はこのまま、[本題](#本題)へ移った方が良いです。

### 下準備編
1. [VagrantとVirtualBoxをインストールしよう](#下準備-1-vagrantとvirtualboxをインストールしよう)
2. [社内Proxy下の人のみ実行](#下準備-2-社内proxy下の人のみ実行)
3. [Vagrantで仮想マシンを作成する](#下準備-3-vagrantで仮想マシンを作成する)
4. [forwarded_portとpublic_networkの違い](#下準備-4-forwarded_portとpublic_networkの違い)

### 本題編
1. [Windows上でVagrantで作成し、仮想マシンでDockerを使用する。](#本題-1-windows上でvagrantで仮想マシンを作成しdockerを使用する)
1. [Vagrant内でhttpdのコンテナを作成し、Windows、スマホ端末からhttpdのページを見る。](#本題-2-vagrant内でhttpdのコンテナを作成しwindowsスマホ端末からhttpdのページを見る)

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

## ホストPC
| Type | Version |
|:--- | :--- |
| Windows10 | Home |
| 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 |

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

- VirtualBoxでCentOSの環境が作成される。
- Vagrantfileが作成される
- [下準備終了後の環境](https://github.com/mokusen/qiita-vagrant-docker/tree/master/vagrant-init/Vagrantfile)

## 下準備 1. VagrantとVirtualBoxをインストールしよう
URLだけ示すので、検索してやり方は探しましょう。
各種Versionについては怖ければ、上記で示した利用環境に合わせましょう。
大抵は最新Versionを選択してインストールすれば問題ないです。
### Vagrant
https://www.vagrantup.com/downloads.html

### VirtualBox
https://www.virtualbox.org/wiki/Downloads

## 下準備 2. 社内Proxy下の人のみ実行
社内Proxy下で今後の作業を行うと、Proxyにもれなく引っかかり、ダウンロード出来なくなります。

### ホストPC側のProxy設定
#### コマンドで設定したい
powershellを開き、以下のコマンドを実行

```powershell:command
# SomeAddress=ドメイン(test.co.jpとか)
# PortNumber=ポート番号(8000とか)
set http_proxy=proxy.SomeAddress:PortNumber
set https_proxy=proxy.SomeAddress:PortNumber
```

#### GUIで設定したい
コマンドより、マウス動かしたり面倒くさいです。悪しからず。

1. スタートメニューで右クリックしてシステムを選択
2. 右上のシステム情報を選択(全画面表示にしないと表示されないと思います)
3. 左真ん中あたりのシステムの詳細設計を選択
4. 上側のタブが詳細設計であることを確認して、環境変数を選択
5. ユーザー環境変数の新規を選択
6. 変数名と変数値に以下の値を入力し、OKを選択

~~~
# SomeAddress=ドメイン(test.co.jpとか)
# PortNumber=ポート番号(8000とか)
変数名(N): http_proxy
変数値(V): proxy.SomeAddress:PortNumber
~~~

もう一度6と同じように操作し、以下の値を入力し、OKを選択(httpsのsを忘れないように)

```
# SomeAddress=ドメイン(test.co.jpとか)
# PortNumber=ポート番号(8000とか)
変数名(N): https_proxy
変数値(V): proxy.SomeAddress:PortNumber
```

あとは全てOKを押して終了です。

#### pluginを追加する
ゲストOSのProxy設定を簡単に行ってくれるpluginです。
これをインストールしましょう。

```bash:command
vagrant plugin install vagrant-proxyconf
```

## 下準備 3. Vagrantで仮想マシンを作成する
Vagrantでは必要な項目が存在します。

- 使用するBox
- Vagrantfileを作成するディレクトリ

Boxとは、仮想環境のimageに当たります。
今回ですと、使用するBoxはCentOSって感じです。
入手先は`https://app.vagrantup.com/boxes/search`で探すのが一番楽です。
今回は`https://app.vagrantup.com/bento/boxes/centos-7`を使います。
powershellを開いて、Boxを取得します。（ディレクトリはどこでも大丈夫です）

```powershell:command
# vagrant box add {boxに付ける名前} {URL}
# boxに付ける名前：centos-7
vagrant box add centos-7 https://app.vagrantup.com/bento/boxes/centos-7
```

ディレクトリは、Vagrantfileを設置するところなので、お好きなところでやりましょう！
powershellを開き、ディレクトリ作成して、Vagrantの初期化をします。

```powershell:command
mkdir vagrant-project
cd vagrant-project
# vagrant init {boxに付けた名前}
# boxに付けた名前：centos-7
vagrant init centos-7
```
これでvagrant-projectフォルダには.vagrantとVagrantfileが存在するはずです。

## 下準備 4. forwarded_portとpublic_networkの違い
違いは簡単でportで選択するか、ipアドレスを選択するかです。
先程作成した、Vagrantfileを開くと、それぞれ以下のように書かれています。

### forwarded_port
> Create a forwarded port mapping which allows access to a specific port
> within the machine from a port on the host machine. In the example below,
> accessing "localhost:8080" will access port 80 on the guest machine.
> NOTE: This will enable public access to the opened port
> config.vm.network "forwarded_port", guest: 80, host: 8080

簡単に言うとhostに設定したportをguest側にフォワードする。ってことです。
なので`http://localhost:8080`と入力してやればguestの80番ポートへ接続できます。

### public_network
> Create a public network, which generally matched to bridged network.
> Bridged networks make the machine appear as another physical device on
> your network.
> config.vm.network "public_network"

簡単に言うと、あなたのホストPCのネットワークとゲストPCのネットワークを合体する。ってことです。
ホストPCのネットワークを調べ方は簡単です。
powershellを開いて

```bash:command
ipconfig
```
と入力してあげれば、以下のような情報が出てきます。

```shell-session:ipconfigのresult
イーサネット アダプター ローカル エリア接続:

   接続固有の DNS サフィックス . . . . .:
   IPv6 アドレス . . . . . . . . . . . .: 見せられないよ！
   一時 IPv6 アドレス. . . . . . . . . .: 見せられないよ！
   リンクローカル IPv6 アドレス. . . . .: 見せられないよ！
   IPv4 アドレス . . . . . . . . . . . .: 192.168.150.25
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: 見せられないよ！
                                          192.168.150.1
```
ここのIPv4アドレスがあなたのホストPCのネットワークってことになります。
なので、public_networkは、このまま実行すれば、192.168.150.??をIPアドレスとします。
??の部分はランダムで選ばれます。
ランダムでは困るなーっていう場合は、設定することが出来ます。

```ruby:Vagrantfile
config.vm.network "public_network", ip: "192.168.150.12"
```
これで常に192.168.150.12がゲストPCのIPアドレスとなり、ネットワークを指します。やったね！

※ 192.168.150といった、前3つの数字は必ずホストPC上で確認したipconfigの値を使用します。
※ 192.168.33.100とかやってもホストPCのネットワークでは無いので、繋がりません。

### 今回使うのは、public_network
今回はLAN環境を手に入れたいのでforwarded_portでは、スマホから確認できません。
なのでpublic_networkを使用していきます。

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

- Vagrantで作成したCentOS環境でDockerが使用できる。
- [本題1終了後の環境](https://github.com/mokusen/qiita-vagrant-docker/tree/master/vagrant-docker/Vagrantfile)
- PC、スマホからhttpdのページを確認することができる。
- [本題2終了後の環境](https://github.com/mokusen/qiita-vagrant-docker/tree/master/vagrant-finish/Vagrantfile)

## 本題 1. Windows上でVagrantで仮想マシンを作成し、Dockerを使用する。
さて、ざっくりとした下準備が出来ました。
今度はVagrantで作成したCentOS環境にDockerをインストールしていきます。

### Vagrantfileの設定
Vagrantfileでは、shellコマンドを実行させる事ができます。
このshellコマンドはrootユーザーで実行されるので、sudoは必要ありません。

```rb:Vagrantfile
config.vm.provision "shell", inline: <<-SHELL
  yum update
  yum remove docker docker-common docker-selinux docker-engine
  yum install -y yum-utils device-mapper-persistent-data lvm2
  yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  yum makecache fast
  yum -y install docker-ce
  gpasswd -a vagrant docker
  curl -L https://github.com/docker/compose/releases/download/1.23.0-rc3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
  chmod +x /usr/local/bin/docker-compose
  systemctl start docker
  systemctl enable docker
SHELL
```

社内Proxyがある方は以下の設定をVagrantfileに追加して下さい。

```rb:Vagrantfile
# SomeAddress=ドメイン(test.co.jpとか)
# PortNumber=ポート番号(8000とか)
if Vagrant.has_plugin?("vagrant-proxyconf")
    config.proxy.enabled  = true
    config.proxy.http     = "http://SomeAddress:PortNumber"
    config.proxy.https    = "http://SomeAddress:PortNumber"
    config.proxy.no_proxy = "localhost,127.0.0.1"
end
```

上記の内容をVagrantfileに追記すれば、Dockerの環境整備は終了です。
以下は上記の内容にコメントをつけたものです。

```bash:Vagrantfile補足あり
yum update
# dockerが存在する場合削除する
yum remove docker docker-common docker-selinux docker-engine

# dockerを入れるために必要なものをインストールする
yum install -y yum-utils device-mapper-persistent-data lvm2

# yumリポジトリにdocker-ceリポジトリを追加する
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# CentOSにDockerを入れる場合
yum makecache fast

# docker-ceをインストール
yum -y install docker-ce

# ユーザー：vagrantをグループ：Dockerに追加する(管理者権限を付与する)
gpasswd -a vagrant docker

# docker-composeをgithubから取得し、/usr/local/bin/docker-composeへ保存する
curl -L https://github.com/docker/compose/releases/download/1.23.0-rc3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

# docker-composeファイルへのアクセス権限を付与する
chmod +x /usr/local/bin/docker-compose

# dockerをスタートさせ、常時起動するよう、設定する
systemctl start docker
systemctl enable docker
```
このようにVagrantfileを編集したら、Docker環境の構築は完了です。

### Dockerがインストールされているか確認
ホストPCのVagrantfileがあるディレクトリでPowershellを開きましょう。
そこでVagrantにsshでログインして確認します。

```bash:command
# vagrantの起動コマンド
vagrant up

# vagrantにログイン
vagrant ssh
```
次にDockerがインストールされているか確認します。

```bash:command
docker --version
```
入っていれば以下のような内容が出力されます。

```shell-session:result
Docker version 18.06.1-ce, build e68fc7a
```

次にdocker-composeがインストールされているか確認します。

```bash:command
docker-compose --version
```
入っていれば以下のような内容が出力されます。

```shell-session:result
docker-compose version 1.23.0-rc3, build ea3d406e
```
### permission error時の対処
permission errorが出る場合は、以下の設定を忘れているか、間違えている可能性が高いです。

```rb:Vagrantfile
# vagrantはデフォルトのユーザー名。意図的に変えている場合は変更する。
# chmodはアクセス権限の変更。
config.vm.provision "shell", inline: <<-SHELL
  gpasswd -a vagrant docker
  chmod +x /usr/local/bin/docker-compose
SHELL
```

## 本題 2. Vagrant内でhttpdのコンテナを作成し、Windows、スマホ端末からhttpdのページを見る。
さて、ここまでお疲れ様です。
あとはDockerコマンドでhttpdのコンテナを作成するだけです！

ここからは以下の手順で行います。
1. [Vagrantfileを編集して、public_networkの設定を入れる](#1-vagrantfileを編集してpublic_networkの設定を入れる)
2. [Vagrantを再起動する](#2-vagrantを再起動する)
3. [VagrantにログインしてDockerコマンドを入力してhttpdのコンテナを作成する。](#3-vagrantにログインしてdockerコマンドを入力してhttpdのコンテナを作成する)
4. [(おまけ)コマンド説明](#4-おまけコマンド説明)
5. [(おまけ)docker-composeを使用してhttpdのコンテナを作成する。](#5-おまけdocker-composeを使用してhttpdのコンテナを作成する)

### 1. Vagrantfileを編集して、public_networkの設定を入れる
ホストPCのVagrantfileを開き、次のコードを追加しましょう。
※[下準備4](#下準備-4-forwarded_portとpublic_networkの違い)を参照して下さい。

```rb:Vagrantfile
config.vm.network "public_network", ip: "192.168.150.12"
```

### 2. Vagrantを再起動する
追加したら、Vagrantを再起動しましょう。

```bash:command
vagrant reload
```

### 3. VagrantにログインしてDockerコマンドを入力してhttpdのコンテナを作成する。
次のコマンドをさくっと入力しましょう。

```bash:command
vagrant ssh
docker run --name httpd-container -d -p 80:80 httpd
```

これでhttpdのコンテナが作成できます！
[http://192.168.150.12](http://192.168.150.12)にアクセスしてみましょう。
下のような質素なページが表示されれば、成功です。
![qiita.PNG](https://qiita-image-store.s3.amazonaws.com/0/262838/12b405fe-5c6c-96d6-a295-3d2f34c6e715.png)

※ 注意：192.168.150.12は自身が設定したpublic_networkの値を使用して下さい。
※ 間違いなく192.168.150.12ではアクセス出来る方はいないと思います。

### 4. (おまけ)コマンド説明
```bash:command
--name httpd-container
```
これはhttpdのコンテナの名前をhttpd-containerという名前にする機能です。

```bash:command
-d
```
バッググラウンドで実行するという機能です。

```bash:command
-p 80:80
```
ホストPCの80番ポートからゲストPCの80番ポートへ接続する機能です。

```bash:command
httpd
```
これは使用するDockerImageというものです。必ず使用するDockerImageはコマンドの最後に記述します。

### 5. (おまけ)docker-composeを使用してhttpdのコンテナを作成する。
せっかくdocker-composeをインストールしたので使ってみましょう！
分からないという方や、難しいんでしょ？と思うかもしれませんが
慣れるとdockerコマンド打つより管理が楽に感じます。

#### 下準備
下準備として、vagrant-projectディレクトリでdocker-compose.ymlというファイルを作成して下さい。

#### 本題
Vagrantは、Vagrantfileを置いてあるホストPCのディレクトリを、ゲストPCと共有します。
例えば、ホストPCでC:\Users\YourName\vagrant-projectというディレクトリを使用していたら
ゲストPCの/vagrantに共有化されます。

こんな感じ！
#### ホストPC
```powershell:command
# ls：ファイルやディレクトリの情報を表示するコマンド
PS C:\Users\YourName\vagrant-project> ls
ディレクトリ: C:\Users\YourName\vagrant-project
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2018/10/22     23:07                .vagrant
-a----       2018/10/22     23:03              0 docker-compose.yml
-a----       2018/10/22     23:06           3091 Vagrantfile
```

#### ゲストPC
```bash:command
PS C:\Users\YourName\vagrant-project> vagrant ssh
# cd：ディレクトリの移動
[vagrant@localhost ~]$ cd /vagrant
[vagrant@localhost vagrant]$ ls
docker-compose.yml  Vagrantfile
```
同じファイルが存在することが分かったはず。
ホストPCでファイルを追加しても、ゲストPCでファイルを追加しても、どちらにも共有されます！

この機能を使ってホストPCでdocker-compose.ymlを編集してみましょう。

```yml:docker-compose.yml
version: '3'
services:
  web:
    image: httpd
    container_name: httpd
    ports:
      - "80:80"
```
保存したら、次のコマンドを打ってみましょう！

```bash:command
docker-compose up -d
```

最後に[http://192.168.150.12](http://192.168.150.12)にアクセス出来たら完了です。
下のような質素なページが表示されれば、成功です。
![qiita.PNG](https://qiita-image-store.s3.amazonaws.com/0/262838/12b405fe-5c6c-96d6-a295-3d2f34c6e715.png)
お疲れ様でした！
※ 注意：192.168.150.12は自身が設定したpublic_networkの値を使用して下さい。
※ 間違いなく192.168.150.12ではアクセス出来る方はいないと思います。

#### (おまけ)docker-compose説明
今回使用したものだけ、説明します。

```yml:docker-compose.yml
# version：docker-composeのファイル形式。この環境では3。
version: '3'
# services：常套文句
services:
  # web：DockerのDNS上に登録される名前。好きな名前で良い。
  web:
    # image：docker runの最後に付けていたDockerImageの名前。
    image: httpd
    # container_name：docker runで付けていた、--nameの設定
    container_name: httpd
    # ports：docker runで付けていた、-pの設定
    ports:
      - "80:80"
    # portsの書き方はどっちでも大丈夫
    ports: "80:80"
```