VirtualBox + Vagrant + DockerによるOSに縛られないコンテナ環境セットアップ

## 自己紹介

Qiita 初投稿となります。

私は、大量の退職エントリが出たりいろんな行動により時折話題になる一族の末端の末端で新人ITエンジニアをやっております。

そして、退職エントリのなかでの伝承によく似た開発環境(詳しくは述べません)の中、
クラウドなのにハイパーバイザ型のVMware vSphereを駆使して環境構築やら、
Pythonと計算式抜きで機械学習やら、
とにかくSQLとにらめっこするソフトウェア開発やら
を頑張ってまいりました。

しかしここ最近上司の英断により先行してエンジニア向けに開発用のマシンが与えられました。

具体的な現在のマシンスペック：

- 64bitのWindows10 Pro
- core i7のCPU
- 16GBのRAM
- 256GBの爆速SSD
- ついでにGPU付き
- VagrantによるLinux検証環境の構築は当然可能（後述）
- WSLによるLinuxそのものなコマンド操作の実現（後述）

こんな感じでWindows環境であるならば現時点で最良の開発環境です。

学生時代はWindowsでゲームをやりつつ小説と絵をゴリゴリつくる、蔑称ドザーでした。しかし現在の私は紆余曲折あり、家の中ではApple製品に囲まれ、あるインフラエンジニアに会社でLinuxを見せられながら一年間育てられた経緯もあり、家ではLinuxの仮想マシンを使い、ローカル環境に影響が出づらいように開発を進めてきた、蔑称マカーでもあります。

このためここ最近新しいバージョンの登場で話題になった、WindowsでもLinux操作が可能となるWSL1(Windows Subsystem for Linux)+UbuntuによってUnix系システムのMacのターミナルみたいにできないものかと試してきました。

実際WSLはLinuxそのもので非常に使いやすく、マカーな私もすぐさまハマりました。それにしてもこれ最高です。

早速macでVagrantを使えるようにするように、WSLとVagrantを合体させて、仮想マシンを動作させられるようにしたりしていました。

## Hyper-VとVirtualBox、共存できず

しかしVagrantを使っているなかでDockerをここ最近使えるようにしたとき、環境がVagrantの操作対象であるVirtualBoxが使えなくなってしまいました。

以下の記事によると、Docker for WindowsはHyper-Vを使用していて、ハイパーバイザ型であるHyper-VはCPUのIntelの仮想化支援技術、VT-X(intel Virtualization Technology)を占有してしまい、結果としてホスト型であるVirtualBoxがVT-Xを使えないために、VirtualBoxが起動しなくなっているそうです。


[VT-xとHyper-VとVirtualBoxの関係についてのメモ](https://qiita.com/tettsu__/items/1f0cb8a752757d76ebbd)

以下の興味深い記事も読ませてもらいましたが、
私の会社の環境ではうまくいきませんでした。

[VirtualBox 6.0 から Hyper-V と共存できるはず](https://qiita.com/takotakot/items/94d3218cf8de5b2c1da8)


結局、Docker for Windowsはアンインストールし、Hyper-Vを無効にすることにしました。意外にもWSLを使うための道は険しい......

## 今回の内容

というわけで、本来なら  
[Windows × Hyper-V] + [Docker for Windows]

をとるところなのですが、Macとほとんど同じように遂行可能で環境の設定をがんばらなくてもWSLを使用可能な、  
[something OS × (Virtual box + Vagrant)] + [Docker for Linux]

の組み合わせをまとめて、セットアップのところまでいきたいと思います。Docker Composeなどを使った実際の構築はまた元気がでたときに......

今回の基盤のアーキテクチャは以下の右側の黄色線のようになります：
![docker_ar.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431414/30688c30-b634-b866-915d-6aa4807e82a4.jpeg)



ただ文字を並べて書いただけのものですが、線を引いている場所がWindowsにおいてかなり重大になります。

Docker for Windowsでは、インストールする際にHyper-Vを使用し、そこにはLinux仮想マシンが構築されていました。

つまり、Docker for Windowsは本質的に仮想マシンの上にコンテナをつくることになります。これをWSLで実施しようとするとさらにインストールする資材が増え、おまけにうまく使えないケースが出てきます。というか私はうまく使えず挫折しました。

そこで、このアーキテクチャを自分でVirtual boxとVagrantで再現すれば、VagrantでのWSLのすり合わせさえ終わらせれば簡単に構築できるのではないかと考えました。  
少し作業が増え,
ハイパーバイザ型ではなくホスト型となるため限界まで性能を高めることは厳しいかもしれませんが、OS間の違いを吸収することができます。コマンドプロンプトを絶対に回避し、Unix系システムを確実に使おうという、もはや固執に近いものですね......  
まだ私は機械学習などで全力投球をしないといけないとかそういうのもないので、本番環境でなければこれで問題ありません。

ちなみにWSL2は以下のニュース記事によればHyper-Vを使用した完全なLinuxにするようなので、正式にリリースされたらWindowsではわざわざこの手順を踏むまでもなくDockerをWSLへ直インストールできるようになる可能性が高そうです。  
しかしいますぐWindowsのWSL1でなんとかしたい私みたいな人向けに書かせていただきます。

[完全なLinuxがWindows 10上で稼働する？　「WSL 2」とは(2019年06月14日 05時00分 公開)](https://www.atmarkit.co.jp/ait/articles/1906/14/news019.html)

2019/06/22 
WSL1でVagrantを操作していると色々な不具合やエラーが出てしまいまだ解消できそうにないので一旦封印することにしました、せつない。

## ちなみに

Macでの場合は以下の記事でサクッと構築できてUnix系システムとしてガンガンコマンドを使えましたので、元も子もないですがmac使用時はこちらがよいかもしれません。  

[DockerをMacにインストールする (更新：2018/5/14)](https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81)

またWindowsの方もWindows10 ProもしくはEnterprise/Educationエディションで、Hyper-Vが使えてリソースが多少あり、WSLを使うつもりが特にないという方の場合は、以下の手順でコンテナそのものは構築できるのでよいかもしれません。

[無償の「Docker for Windows」で手軽にLinuxコンテナを利用する (1/2)](https://www.atmarkit.co.jp/ait/articles/1609/01/news053.html)

[WindowsでDocker環境を試してみる](https://qiita.com/fkooo/items/d2fddef9091b906675ca)

ここから先は、このふたつでは要件を満たせない人向けの内容となります。なお32bitの場合は全く試しておらず、至るソフトで引っかかるかもしれないのであまり推奨しません。

## 追記

久々に環境いじりしましたが、Windows 11 Proをお使いの方はこちらの記事のほうが簡単にセットアップできるのでおすすめです。

https://qiita.com/GCkurabe/items/d522ec49cf165f14f76c


## 対象読者

- 仮想マシンで開発してきてDockerなどのコンテナ技術も知りたい初心者
- かつ社内ではドザー(Windows使い)、社外ではマカー(Mac使い)だけど、どの作業環境でもUnix系システムでコンテナを使いたい人
- かつ正直Vagrantで開発環境ごとに何度も作りたくはない人
- かつVagrantなどなど毎度社内で環境や基盤をつくる手順を書かなければならない人
- つまり私


## 前提条件

事前に以下の内容の実施をお願いします。
- 以後の内容のすべてにおいて、自環境におけるプロキシ関連の問題を解決すること
(会社の中だとかなりプロキシで引っかかると思いますので社内の有識者に確認をすることを推奨します)

- Virtualbox、Vagrantのインストールを完了していること
- Vagrant用のCentOS7をすでに使用可能にしていること

コマンドプロンプトの代わりにWSL1を使う場合

- WSLを使用可能にしていること
- WSL1でVagrantを使用可能にしていること  
[参考：Windows10 WSL から Vagrant を起動する](https://qiita.com/apatchk/items/8b1029ceaee60d3e18a2)




## 今回の使用環境

- macOS Mojave 10.14.5
- VirtualBox 6.0.4
- Vagrant 2.2.4
- CentOS Linux release 7.6.1810 (Core)
- Docker 18.09.6

## 実施する内容
1. VagrantによるDocker用仮想マシンの作成
2. Dockerインストール
3. Dockerの起動
4. コンテナの起動

## 1. VagrantによるDocker用仮想マシンの作成
事前にDocker用のフォルダを作成します。

```
$ vagrant init
```

Vagrantfileが作成されているので以下の内容に修正します(vm.box名は各自centos7のbox名をどう入れたかによって変わるので読み替えてください)。

2019/09/27追記

以下の設定ではprivate_networkのみ有効にしています。つまり自分のマシンからのみアクセスできる状態です。もしも他のマシンからも結果を見たいときはforwarded_portの行のコメントアウトを外して有効にしてください。どちらの設定でもVMから外のネットワークにつなげることができます。ただし、プロキシの檻を超えられたら、なのですが......

```  
Vagrant.configure("2") do |config|
config.vm.box = "centos7"  
#config.vm.network "forwarded_port", guest: 80, host: 8800  
config.vm.network "private_network", ip: "192.168.33.10"  
end  
```

完了したら仮想マシンを起動します。

```
$ vagrant up  
 ```

ちなみに、ここで書くまでもないかもしれませんが終了するときは以下のようにコマンドを打ちます。

```
$ vagrant halt  
 ```

DockerインストールをするためVagrantのSSH機能を使用してログインします。特にパスワードなしで入れます。

 ```
 $ vagrant ssh  
  ```

特に設定してない状態だとroot権限に移行するときはvagrantと入力すればよいです。つまりセキュリティ的な話は今回はなしです。

## 2. Dockerインストール（2019/09/27追記）

昨日、下の「2. Dockerインストール」をベースにdockerをインストールしようとしたのですがうまくいかなくなってました。調べてみたらバージョンが上がってやり方が変わったようです。以下のDockerの公式ドキュメントを参考の上実施して、終わったら「 3. Dockerの起動」に進んでください。

[Docker-dics-ja 1.9.0b : http://docs.docker.jp/v1.9/engine/installation/centos.html](http://docs.docker.jp/v1.9/engine/installation/centos.html)


## 2. Dockerインストール(2019/09/27追記　できなくなってます)


以下の記事を参考にDockerのインストールを遂行します。

[CentOS7にDockerをインストールする](https://qiita.com/inakadegaebal/items/be9fecce813cebec5986)

[公式ドキュメント(英語)](https://docs.docker.com/install/linux/docker-ce/centos/)

[公式ドキュメント(日本語)](http://docs.docker.jp/engine/installation/linux/docker-ce/centos.html)

念の為Dockerが入っていないか確認しましたが特にいないようなので問題ありませんでした。

```
$ docker version  
bash: docker: コマンドが見つかりません  
```

リポジトリを使ったインストールをしますので、リポジトリのセットアップをやります。まずは必要なパッケージをインストールします。  
ここでいれるものは二種類で合計3つ:  

- yum-utils : yum-config-manager ユーティリティのこと。
言葉通り、yum設定管理の便利なソフトのこと。

- device-mapper-persistent-data
- lvm2
:Linux 上で多くの高度なボリューム管理技術を支えるカーネル・ベースのフレームワーク、devicemapperストレージ・ドライバを使用するためのソフト。

```  
sudo yum install -y yum-utils device-mapper-persistent-data lvm2  
```

リポジトリのセットアップをします。

```
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo  
```  

yum パッケージ・インデックスを更新します。

```
$ sudo yum makecache fast  
```  

今回は試しに最新バージョンでインストールを実施します。yを二回押すことになりました。

```
$ sudo yum install docker-ce  
```  

試しにDockerのバージョンを確認してみます。特に起動していないため、Daemonと接続できないと表示されています。

```
$ docker version  
Client:  
Version:           18.09.6  
API version:       1.39  
Go version:        go1.10.8  
Git commit:        481bc77156  
Built:             Sat May  4   02:34:58 2019  
OS/Arch:           linux/amd64  
Experimental:      false  
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?  
```  


## 3. Dockerの起動
Dockerを起動します。  

```
$ sudo systemctl start docker  
```  
すると先ほどでていたdaemonと繋がらないというフレーズは消えました。

```
$ docker version  
Client:  
 Version:           18.09.6  
 API version:       1.39  
 Go version:        go1.10.8  
 Git commit:        481bc77156  
 Built:             Sat May  4   02:34:58 2019  
 OS/Arch:           linux/amd64  
 Experimental:      false  

Server: Docker Engine - Community  
 Engine:  
  Version:          18.09.6  
  API version:      1.39 (minimum version 1.12)  
  Go version:       go1.10.8  
  Git commit:       481bc77  
  Built:            Sat May  4 02:02:43 2019  
  OS/Arch:          linux/amd64  
  Experimental:     false  
```  

## 4. コンテナの起動

docker が正しくインストールされているのを確認するため、 hello-world イメージを実行します。

```
$ sudo docker run hello-world  
```  

中をみてみるとこんな感じであいさつされています。

```
Hello from Docker!  
```  

このコマンドはテスト用イメージをダウンロードし、コンテナ内で実行して、情報を表示したあと終了するそうです。

最後にOS起動時にDockerを自動起動にします。

```bash:  
$ systemctl enable docker  
```  

セットアップの内容は以上となります。

## おわりに
とりあえずセットアップができました。  
私もまず社内のWSLでこれらをまたやってみて、
そこからDockerでのコンテナの構築などを実施して、最終的にはDocker-composeなどに踏み込んでDjangoやCakePHPでの実行環境を共有できるようにしたいと思います。  

それにしてもmarkdownは一昨日覚えたばかりですが、Atomでサクサクかけて楽ですね......

2019/06/22 続きの記事書きました。
[docker-composeを使用したコンテナでの開発環境セットアップ(CakePHP3)](https://qiita.com/GCkurabe/items/d1d49e08b5666d30d3b1)