Vagrantを使った仮想環境実例（Debian 8.2.2, MySQL 5.6, PHP 7.0, Apache 2.4）

Qiita初投稿です。
PHP7環境へリプレースする案件があり、どのくらい動くか調査することになりました。
せっかくなので、Vagrantの仮想環境構築例として投稿します。
以下のように構築します。

- Debian 8.2.2, MySQL 5.6, PHP 7.0, Apache 2.4
- バーチャルホストは使わない
- Apacheの設定も最小限（ドキュメントルートの場所変更、.htaccessの有効化程度）
- 公開されているBoxを使う
- 仮想環境の構築にVagrantを使う
- Vagrantの共有フォルダ機能を使う
- ~~今回はプロビジョニングファイルの作成はなし~~ → 中途半端なプロビジョニングファイルを作成、次回以降役立てる


#Boxの取得

Box取得は[ATLAS](https://atlas.hashicorp.com/)へサインインし、公開されているBoxを探しました。
ATLASサイト内での操作は割愛します。
今回は「debian/jessie64」（Debian 8.2.2）を使用します。

```zsh
% vagrant init debian/jessie64
```

この時点でvagrant-vbguest プラグインをインストールします。共有フォルダマウントに必要なGuest AdditionsをゲストOSにインストールしてくれます。バージョンが古くてマウントが上手くいかない場合も最新の状態にアップグレードしてくれます。[Vagrant の Box の Guest Additions を最新化する方法](http://weblabo.oscasierra.net/vagrant-vbguest-plugin-1/)を参考にしました。

```zsh
% vagrant plugin install vagrant-vbguest
```

#設定ファイルの調整

Vagrantfileという設定ファイルができるので、これを調整します。

IPアドレスを設定します。

```zsh:Vagrantfile
---
# config.vm.network "private_network", ip: "192.168.33.10"
---
+++
config.vm.network "private_network", ip: "192.168.33.10"
+++
```

共有フォルダの設定です。ホストOSの「Vagrantfile」があるディレクトリをゲストOS上で編集できるようになります。後でインストールするApacheのドキュメントルートの都合上、ここでは/var/www/html配下をホストOS側のファイル/ディレクトリと共有させます。

```zsh:Vagrantfile
---
# config.vm.synced_folder "../data", "/vagrant_data"
---
+++
config.vm.synced_folder "", "/var/www/html", owner: "vagrant", group: "vagrant", mount_options: ["dmode=777", "fmode=777"]
+++
```

#仮想環境の立ち上げ
仮想環境を立ち上げます。Vagrantfileのあるディレクトリで下記コマンドを実行します。

```zsh
% vagrant up
```

#仮想環境へSSHで入る
SSHで仮想環境へ入り、設定をしていきます。

```zsh
% vagrant ssh
```

#パッケージのインストール

apt-getコマンドなどを使ってパッケージのインストールを行います。root権限が必要なのでコマンドの頭にsudoをつけます。

##Apache 2

```zsh
% sudo apt-get -y install apache2
```

基本的にapt-get一発ですが、設定を少しだけ変えておきます。

- ドキュメントルートの変更（/var/www/html→/var/www/html/公開ディレクトリに変更）
- .htaccessの有効化

Debianは思想上設定ファイルがあちこちに散らばっていてややこしいのですが、下記ファイルを調整すればOKです。

```text:/etc/apache2/sites-available/000-default.conf
---
        DocumentRoot /var/www/html
---
+++
        DocumentRoot /var/www/html/公開ディレクトリ
        <Directory /var/www/html/公開ディレクトリ>
            AllowOverride All
        </Directory>
+++
```

変更後、設定を適用させるためにApacheを再起動します。

```zsh
% sudo /etc/init.d/apache2 restart
```

##MySQL 5.6

公式サイトの[A Quick Guide to Using the MySQL APT Repository](https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/)（英語）にインストール方法が記載されています。
ダウンロード先は[Download MySQL APT Repository](http://dev.mysql.com/downloads/repo/apt/)です。ここにレポジトリファイルがあります。

```zsh
% wget http://dev.mysql.com/get/mysql-apt-config_0.6.0-1_all.deb
% sudo dpkg -i mysql-apt-config_0.6.0-1_all.deb
% sudo apt-get update
% sudo apt-get -y install mysql-server
```

dpkgコマンドで、MySQLのバージョンなどを設定できる画面が表示されます。ここでバージョンを5.6に変更します。
apt-get installコマンドの途中でrootパスワードの入力を求められるので覚えておきます。

インストール後、動作確認を兼ねてMySQLクライアントに接続してみます。パスワードは今設定したやつです。
```zsh
% mysql -u root -p
```

MySQLクライアントでデータベースを1つ作っておきます。（後でホストOSからの接続テストに使います。）

```zsh
mysql> CREATE DATABASE データベース名 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
```

###ホストOSのDBクライアントから接続してみる

ホストOSのDBクライアントから接続できると便利です。（もちろんゲストOS上でDBの操作はできるので必須ではありません。）以下はSequel Proでの接続例です。

| 設定項目 | 設定値 |
|:-----------|:------------|
| 名前           | コネクション名※任意            |
| MySQLホスト           | 127.0.0.1※標準の場合            |
| ユーザ名           | DBユーザー名            |
| パスワード           | DBパスワード            |
| データベース名           | DB名            |
| ポート           | 3306※デフォルトの場合            |
| SSHホスト           | Vagrantfileに記載したIPアドレス            |
| SSHユーザ           | vagrant            |
| SSHパスワード           | vagrant            |
| SSHポート           | 22※デフォルトの場合            |

SSHホストはVagrantfileを調整したときにIPアドレスを調整しています。今回は192.168.33.10です。

##PHP7.0
今回使用したBoxでPHP7.0をインストールしようとしたときにハマりました。
sources.listの編集が必要でした。

```zsh
sudo vi /etc/apt/sources.list
```

```zsh:/etc/apt/sources.list
+++
deb http://packages.dotdeb.org jessie all
deb-src http://packages.dotdeb.org jessie all
+++
```

インストールにGPG keyが必要です。追加してからインストールします。PHP本体の他に付随パッケージもついでにインストールします。libapache2-mod-php7.0は必要です。これがないと必要となるApacheのモジュール（/usr/lib/apache2/modules/libphp7.0.so）インストールされないため、ブラウザでphpファイルを実行できません。

```zsh
wget https://www.dotdeb.org/dotdeb.gpg
sudo apt-key add dotdeb.gpg
sudo apt-get update
sudo apt-get -y install php7.0 php7.0-mysql php7.0-mcrypt php7.0-intl php7.0-fpm php7.0-gd libapache2-mod-php7.0
```

#動作確認

ここまでの設定を行うと、ブラウザからPHP7.0を動かせるようになっているはずです。phpinfoを表示させてみます。先に設定したApacheのドキュメントルートにphpinfo()を実行させるファイルを置いてみます。ホストOSと共有させていて、Vagrantfileのあるディレクトリの中にある公開用ディレクトリになります。

```zsh:phpinfo.php
<?php phpinfo();
```

http://192.168.33.10/phpinfo.php
で設定情報が表示されれば成功です。

#プロビジョニング

構築作業の一部をプロビジョニング化しました。
仮想環境を破棄（vagrant destroy）した後再作成（vagrant up）したときにPHPとApacheのインストールまで行います。
本当はMySQLも自動化したかったのですが、Vagrantのプロビジョニングだと、debconf-set-selectionsコマンドの挙動がおかしくなるのか、実現できませんでした。

##Vagrantfile調整

プロビジョニング設定です。外部のシェルスクリプトを読み込みます。
Vagrantfileのあるディレクトリにprovisionというディレクトリを作りそこにシェルスクリプト（provision.sh）を配置しました。provision.shを読み込むため、Vagrantfileに追記します。（追記箇所はどこでも構いません。「end」行の前でいいと思います。）また、一部の設定ファイル（/etc/apache2/sites-available/000-default.conf）もprovisionディレクトリに配置しておきます。

```zsh:Vagrantfile
+++
  config.vm.provision :shell, :path => "provision/provision.sh"
+++
```

##プロビジョニング用シェルスクリプト

Apache→PHPの順にインストールしています。既にインストール済の場合、処理をスキップさせるため、インストール完了後0バイトのファイルを作成しています。このファイルの有無によって処理をスキップします。


```zsh:provision/provision.sh
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update

if [ ! -e /etc/installed ]; then
    sudo mkdir /etc/installed
fi

INSTALLED=/etc/installed/apache
if [ ! -f ${INSTALLED} ]; then
    sudo apt-get -y install apache2
    sudo cp /var/www/html/provision/000-default.conf /etc/apache2/sites-available/000-default.conf
    sudo /etc/init.d/apache2 restart
    sudo touch /etc/installed/apache
fi

INSTALLED=/etc/installed/php
if [ ! -f ${INSTALLED} ]; then
    echo "# Added" | sudo tee -a /etc/apt/sources.list
    echo "deb http://packages.dotdeb.org jessie all" | sudo tee -a /etc/apt/sources.list
    echo "deb-src http://packages.dotdeb.org jessie all" | sudo tee -a /etc/apt/sources.list
    wget https://www.dotdeb.org/dotdeb.gpg
    sudo apt-key add dotdeb.gpg
    sudo apt-get update
    # sudo apt-get -y install php5 php5-cli php5-cgi php5-common php5-dbg php5-fpm php5-gd php5-mcrypt php5-intl php5-mysql php5-xdebug
    sudo apt-get -y install php7.0 php7.0-mysql php7.0-mcrypt php7.0-intl php7.0-fpm php7.0-gd
    sudo touch /etc/installed/php
fi
```