Vagrant + VirtualBoxでWindows上に開発環境をサクッと構築する

最近、Vagrant(ベイグラント)を使い始めてすごい便利だなあと感じたので、Vagrantに関する記事を色々と読んで整理してみました。Windows環境でのセットアップ手順も書いています。
**(※Windows向けの手順を書いていますが、Macでもほぼ同様です)**

2016-02-29時点での最新バージョンを使っています。
Vagrant 1.8.1
VirtualBox 5.0.14


# **Vagrantってなに？**

仮想マシンの簡単な構築や、どこでも同じ環境を再現できるように仮想マシンを管理するためのコマンドラインツールです。
Rubyで実装されていて、Windows、Mac OS X、Linuxで動作します。
Vagrant自体には仮想化機能は無く、VirtualBoxなどの仮想化ソフトのフロントエンドとして機能し、仮想化ソフトの操作を簡単なコマンドで代行してくれます。

公式ページ
http://www.vagrantup.com/


# **Vagrantを使うメリット**

## **超簡単に仮想マシンを構築できます**

通常の仮想化ソフトでは環境構築のために複雑なコマンド操作を行いますが、Vagrantでは数行のコマンドで構築が完了します。これだけでも使う価値あり！


## **環境の差異により発生する不具合を最小限に抑えることができます**

一般的なWebアプリでは、本番環境・ステージング環境・開発環境／ローカル開発環境といった感じで、役割の異なる環境で運用・開発を行っているかと思います。
チームで開発する場合は、各自のローカル開発環境があるはずです。
これらの環境構築をそれぞれが手作業で行った場合、環境に差異が生まれることがあり、開発環境では動くのに本番環境では動かないといったことが出てくる可能性があります。

環境を揃えるには、ChefやAnsibleなどの構成管理ツールを使って、構築手順を自動化するのがオススメです。
構成管理ツールには以下のメリットがあります。

- 構築手順がコード管理可能になる。
- どんな処理を行っているか明確になる。
- 簡単に共有できるようになる。
- 何度でも同じ結果を得ることができる。(冪等性)

また、Vagrantでも同様に仮想マシンの構成をVagrantfileというテキストファイルで管理しており、ファイル内に仮想マシン起動に構成管理ツールを実行するように指定する箇所があります。
このVagrantfileと構成管理ツールの設定ファイルを共有することで、どこでも同じ仮想マシンを再現することができるようになります。
(本番環境はVagrantで構築しないので、構成管理ツールの設定のみ使用します)


# **用語**

## **Boxファイル**
仮想マシン起動時のテンプレートとなるイメージファイル。(一般的なISOファイルとは異なる)
https://app.vagrantup.com/boxes/search に色々なBoxファイルが公開されているので、それを使うのが手っ取り早いです。
自分でBoxファイルを作成することも可能です。

## **Vagrantfile**
仮想マシンの構成を記述するファイル。
主に以下の項目を指定します。

- 起動する仮想マシン指定
- ネットワーク設定
- 共有フォルダ設定
- マシンスペック設定(CPUやメモリの割り当てなど)
- プロビジョニング(シェルスクリプトや構成管理ツールの実行指定)

## **プロバイダ**
仮想化ソフト(仮想環境)のこと。
VagrantではデフォルトでVirtualBoxをサポートしていますが、プラグインをインストールすることでVMwareやParallels、AWS(EC2)などにも対応可能です。

## **プロビジョニング**
ミドルウェアのインストールや設定を行うツール。
ここではシェルスクリプトや、構成管理ツール(Chef、Puppet、Ansibleなど)のことを指します。
Vagrantfile内で指定する。

## **共有フォルダ**
ローカルと仮想マシン間でファイルを同期する機能が用意されています。
デフォルトでは、ローカルのVagrantfileがあるフォルダと、仮想マシンの/vagrant が同期されています。
他のフォルダを指定したい場合は、Vagrantfileのconfig.vm.synced_folderに指定する。

## **プラグイン**
vagrant plugin installで後からインストール可能な便利な追加機能。


# **コマンド一覧**

| コマンド                              | 機能                   | 備考                                          |
|:--------------------------------------|:-----------------------|:----------------------------------------------|
| vagrant box add \<name, url, or path> | Box追加                |                                               |
| vagrant box remove \<name>            | Box削除                |                                               |
| vagrant box list                      | Box一覧                |                                               |
| vagrant init [name [url]]             | Vagrantの初期化       | Vagrantfileが作成される                       |
| vagrant ssh                           | sshログイン            |                                               |
| vagrant up                            | 仮想マシン起動         |                                               |
| vagrant halt                          | 仮想マシン停止         |                                               |
| vagrant reload                        | 仮想マシン再起動       |                                               |
| vagrant destroy                       | 仮想マシン削除         |                                               |
| vagrant package                       | パッケージ作成         | 仮想マシンをパッケージングする(Box形式で出力) |
| vagrant plugin install \<name>        | プラグイン追加         |                                               |
| vagrant plugin list                   | プラグイン一覧         |                                               |

よく使うのはこのあたりのコマンド。他にも色々あるのでvagrant -hで確認してみてください。
全てのコマンドは-hオプションを付けて実行することで、各コマンドの詳細なヘルプが表示されます。
例) vagrant up -h,  vagrant box add -h


# **インストール手順**

今回はWindows(64bit)環境にインストールする手順を説明します。
プロバイダは、Oracleが提供しているフリーのVirtualBoxを使用します。インストールする順番はどちらでも良いです。
PCによっては、BIOSの仮想化支援機能を有効にする必要があるかもしれません。

以下からそれぞれのインストーラをダウンロードして、画面の指示に従ってインストールします。
(オプションの変更は不要で、次へ次へと進めば良いです)

Vagrant
https://www.vagrantup.com/downloads.html

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

インストールが終わったら、PCを再起動します。

再起動したら、コマンドプロンプトでインストール確認。
バージョンが表示されれば問題ありません。
環境変数にPathに追加されているので、どこからでも実行できます。

```dummy:コマンドプロンプト
vagrant -v

Vagrant 1.8.1
```


# **仮想マシン構築例**

## **Boxを検索**

https://app.vagrantup.com/boxes/search でインストールするBoxファイルを検索します。

「centos」などで検索するといくつもヒットします。
例えば「bento/centos-6.7」というBoxがありますが、これはユーザ名/Box名という意味です。
bentoというのはChef社のものなので安心して使うことができます。
検索結果一覧でBox名をクリックすると、以下のようにプロバイダに応じて実行すべきvagrantコマンドが記載されているので、こちらを後で実行します。

```dummy:例
virtualbox
Hosted (227 MB)
vagrant init bento/centos-6.7; vagrant up --provider virtualbox
```

## **フォルダを作成**

まず、わかりやすいようにVagrant専用のフォルダを作成します。

```dummy:コマンドプロンプト
mkdir C:\Vagrant & cd C:\Vagrant
```

次に各仮想マシン用のフォルダを作成します。

```dummy:コマンドプロンプト
mkdir centos67 & cd centos67
```

## **Vagrantを初期化**

先ほど確認したコマンドを実行します。

```dummy:コマンドプロンプト
vagrant init bento/centos-6.7
```

centos67フォルダにVagrantfileが作成されます。


## **Vagrantfileを編集**

作成されたVagrantfileをテキストエディタで編集します。

```rb:Vagrantfile
Vagrant.configure(2) do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://atlas.hashicorp.com/search.
  config.vm.box = "bento/centos-6.7"

  '↑ここはvagrant init時に指定したBox名が設定されている'

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # 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.
  # config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network "private_network", ip: "192.168.33.10"

  '↑ここのコメントアウトを外す'

  # 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"
```

## **仮想マシンを起動**

```dummy:コマンドプロンプト
vagrant up
```

上記では、vagrant up --provider virtualboxとなっていたが、デフォルトのプロバイダがVirtualBoxなので特に指定する必要なし。
指定したBoxが登録されていない場合は、自動的にダウンロードしてBox追加(vagrant box add)してくれる。

以下のエラーが出るがWindows版のバグのようなので、~~とりあえず放置。~~

```
Stderr from the command:
chown: changing ownership of `/vagrant': Not a directory
```

上記のエラーを放置していると共有フォルダが使えなくて困るので、[こちら](https://mistymagich.wordpress.com/2015/07/17/windows-virtualbox-5-0-vagrant-1-7-3-%E3%81%A7vagrant-up%E6%99%82%E3%81%AB%E3%82%A8%E3%83%A9%E3%83%BC/)を参考にして暫定対応します。(Vagrant 1.7.4で修正されると書いてるけど直ってないですね)

　
**【共有フォルダのマウントに失敗する場合】**
[こちら](http://qiita.com/ozawan/items/9751dcfd9bd4c470cd82/)を参考に。


## **登録済みBox一覧を表示**

```dummy:コマンドプロンプト
vagrant box list

bento/centos-6.7 (virtualbox, 2.2.3)
```

## **仮想マシンにログイン**

```dummy:コマンドプロンプト
vagrant ssh

エラーメッセージ...
```

Windowsではコマンドプロンプトからsshログインできないので、PuTTYなどのSSHクライアントを使ってログインします。
接続先ホスト名に192.168.33.10、接続先ポートに22を指定してください。

最初はパスワードログインが可能になっているので、以下のアカウントでログインします。

| ユーザー | パスワード |
|:------- |:----------|
| vagrant | vagrant   |
| root    | vagrant   |

とりあえず、これでログインできるようになり、通常のサーバーと同じように操作できると思います。

ログイン後の設定、構成管理ツールの連携方法、カスタムパッケージの作成方法などは別記事にまとめる予定です。

【追記】
構成管理ツール(Ansible)との連携例は [こちら](http://qiita.com/ozawan/items/a4853eb62afef45f5de7) にまとめました。


# **その他、使っていて気付いたこと**

## **プラグインが便利**

オススメのプラグイン

| プラグイン名         | 機能                                               |
|:-------------------- |:---------------------------------------------------|
| sahara               | sandboxモードのON/OFF切替ができるようになる        |
| vagrant-vbguest      | Guest Additionsのバージョン調整を行ってくれる      |
| vagrant-hostsupdater | hostsファイルにエントリ追加・削除を行ってくれる    |
| vagrant-hostmanager  | hostsファイルにエントリ追加・削除を行ってくれる    |
| vagrant-cachier      | yumなどパッケージ管理システムのパッケージをローカルキャッシュして高速化 |

saharaのsandboxモードは、ある時点のOSの状態を記憶しておき、好きな時にロールバックで元に戻せます。
色々試行錯誤したい場合などに有効です。

vagrant-host●●●は、Vagrantfileに記述したIPアドレスとホスト名を元に、hostsファイルにエントリを追加してくれます。これにより仮想マシンにホスト名でアクセスできます。

## **Box管理と仮想マシン管理は別もの**

vagrant destroyで仮想マシンを削除してもBoxとVagrantfileは残る。

vagrant destroy    = 仮想マシン削除
vagrant box remove = Box削除

再度vagrant upを行うと初期状態(vagrant box add直後の状態)で起動することができるので、vagrant up → 作業 → vagrant destroyというサイクルで作業ができる。


## **VagrantとVirtualBoxがローカルに作成するファイル**

かなり容量の大きいファイル(数百MB)を作成して、うまく削除されてなかったりするので、ディスクの空き容量が減ってきた場合は以下を確認して不要なファイルは削除してしまいましょう。

#### **C:\Users\ユーザー名\\.vagrant.d\boxes\以下**

vagrant box addを実行すると、VMDK形式のファイルがコピーされる。
vagrant box removeを実行すると、VMDK形式のファイルが削除される。

#### **C:\Users\ユーザー名\VirtualBox VMs\以下**

vagrant upを実行すると、VMDK形式のファイルがコピーされる。


## **オライリー本も出てました**

http://www.amazon.co.jp/dp/4873116651