vagrant で CentOS7.1 + php7 + mariadb10 の開発環境を作る

php7(と、symfony) + mariadb10 を使うアプリケーション開発のための環境をvagrantで作る方法。  
CentOS7.1のデフォルトyumリポジトリだとphp5.4がインストールされるし、remiリポジトリを追加して云々といろいろ面倒なのでchefにインストールさせるようにする。  
また、開発時にはapacheとかnginxを使わずphpのビルトインサーバーで良いので、ブラウザ確認用のポート(8000)を開けておくのと、symfonyコマンド、composerコマンドをいちいちロードしたくないのであらかじめインストールしておく。  

## 環境等

* ここではWindows10 + ChefDK + Vagrant + VirtualBoxを使用している。
* Vagrantファイルの置き場所は c:/vagrant/sample を想定している

## 基本的な流れ

* Vagrantfileを準備する
* chef cookbook repository 準備
* berkshelf でコミュニティレシピを取り込む
* php7 をインストールするレシピを作成する
* firewalldを設定するレシピを作成する
* vagrant VMに対するjsonファイルを作成する
* VM起動
* 動作確認


## Vagrantfileを準備する

vagrant init コマンドを実行して初期Vagrantfileを作成する。
```
PS > cd c:\vagrant\sample
PS > vagrant init
```


c:/vagrant/sample/Vagrantfile を以下のように編集する

```
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-7.1"
  config.vm.network "private_network", ip: "192.168.33.101"
  config.omnibus.chef_version = :latest
  
  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "1024"
  end
  
  config.vm.provision "chef_zero" do |chef|
    chef.cookbooks_path = ["chef-repo/cookbooks", "chef-repo/site-cookbooks"]
    chef.nodes_path = ["chef-repo/nodes"]
    chef.node_name = "sample"
  end
end
```

## chef cookbook repository 準備

chef generate コマンドでcookbook リポジトリを作成する

```
PS > cd c:\vagrant\sample
PS > chef generate repo chef-repo
```

## berkshelf でコミュニティレシピを取り込む

chef-repo/BerksFileを以下の内容で作成する

```
source "https://supermarket.chef.io"

cookbook 'yum'
cookbook 'yum-remi'
cookbook 'yum-epel'
cookbook 'mariadb'
```

コミュニティレシピをダウンロードする。

```
PS > cd chef-repo
PS > berks vendor cookbooks
```

## php7 をインストールするレシピを作成する

knife cookbook コマンドでphpをインストールするレシピを作成する

```
PS >  knife cookbook create php -o site-cookbooks
```

chef-repo/site-cookbooks/php/recipe/default.rbを以下のように編集する

```
include_recipe 'yum::default'
include_recipe 'yum-remi::default'

%w[
  gd-last
  t1lib
].each do |pkg|
    package "#{pkg}" do
        action [ :install ]
        options "--enablerepo=remi"
    end
end

%w[
  php
  php-cli
  php-common
  php-gd
  php-xml
  php-pdo
  php-mbstring
  php-mysqlnd
  php-opcache
].each do |pkg|
  package "#{pkg}" do
    action :install
    options '--enablerepo=remi-php70'
  end
end

execute "composer-install" do
  command "curl -sS https://getcomposer.org/installer | php ;mv composer.phar /usr/local/bin/composer"
  not_if { ::File.exists?("/usr/local/bin/composer")}
end

execute "symfony-install" do
  command "curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony;chmod a+x /usr/local/bin/symfony"
  not_if { ::File.exists?("/usr/local/bin/symfony")}
end
```

php-gd を使うのに gd-last, t1libが必要なのであらかじめ remiリポジトリからインストールするようにしてある。  
インストールする拡張モジュールは適宜調整。  
また、symfonyコマンドとcomposerコマンドはあとからコマンドラインをたたいてインストールするのではなく、この時点でインストールするようにする。

コミュニティレシピのyum,yum-remiを使うので chef-repo/site-cookbooks/php/metadata.rb に依存レシピを記述する。

```
depends 'yum'
depends 'yum-remi'
```

## firewalldを設定するレシピを作成する

apacheのエイリアス設定とかディレクトリ設定とかやらなくていいのでphpビルトインサーバーを使う。このためにビルトインサーバーが使うポートを開けるようにする。

knife cookbook コマンドでfirewalldを設定するレシピを作成する

```
PS >  knife cookbook create init -o site-cookbooks
```

chef-repo/site-cookbooks/init/recipe/default.rbを以下のように編集する

```
service "firewalld" do
    supports [ :restart, :reload ]
    action [ :enable, :start ]
end

execute "allow port 8000" do
    command "firewall-cmd --add-port=8000/tcp --zone=public --permanent"
    notifies :restart, "service[firewalld]"
end
```

firewall-cmd を使って ポート8000 を開けるようにする。

レシピの名前が "firewalld" でなく "init" なのはロケールとかタイムゾーンとかの初期設定も含めるようにするためでたいして意味はないけど、その辺はレシピ作成ポリシー次第。


## vagrant VMに対するjsonファイルを作成する

以下の内容で chef-repo/nodes/sample.jsonファイルを作成する。

```
{
  "name": "sample",
  "chef_type": "node",
  "json_class": "Chef::Node",
  "normal":{
    "mariadb": {
      "use_default_repository": true,
      "allow_root_pass_change": true,
      "server_root_password": "test",
      "install": {
        "type": "package",
        "version": "10.1.13",
        "prefer_os_package": false
      },
      "mysqld": {
        "options":{
          "collation-server" : "utf8_unicode_ci",
          "init-connect" : "'SET NAMES utf8'",
          "character-set-server" : "utf8"
        }
      },
      "innodb": {
          "log_file_size": "",
          "bps_percentage_memory": false,
          "buffer_pool_size": "256M",
          "log_buffer_size": "8M",
          "file_per_table": "1",
          "open_files": "400",
          "io_capacity": "400",
          "flush_method": "O_DIRECT",
          "options": {

          }
      }     
    },
    "yum": {
      "remi-php70": {
        "repositoryid": "remi-php70",
        "baseurl": "http://rpms.famillecollet.com/enterprise/7/php70/x86_64/",
        "description": "Les RPM de remi de PHP 7 pour Enterprise Linux 7 - $basearch",
        "mirrorlist": "http://rpms.famillecollet.com/enterprise/7/php70/mirror"
      }
    },
    "yum-remi": {
      "repositories": [
        "remi",
        "remi-php70"
      ]
    }
  },  
  "run_list": [
    "recipe[yum]",
    "recipe[yum-epel]",
    "recipe[mariadb::server]",
    "recipe[mariadb::client]",
    "recipe[php]",
    "recipe[init]"
      
  ]
}
```

mariadbのattributesはここで指定する。rootパスワードはdatabag等で書くべきかもしれない。

よくあるvagrantの解説では Vagrantfileに属性とか実行レシピとかを chef.runlist =[] とか chef.json={}とか記述しているけれども最終的には記述したレシピと設定をvagrantではなく実環境に適用したくなるのでnodes/jsonに記述するようにする。

## VM起動

準備ができたらVMを起動する。

```
PS > cd c:\vagrant\sample
PS > vagrant up
```

## 動作確認

適当なディレクトリにphpファイルを作って php ビルトインサーバーを起動し、ホストからアクセスする。

 /vagrant/check/info.php
```
<?php
phpinfo();
```

ビルトインサーバー起動

```
$> php -S 0.0.0.0:8000
```

ホストから http://192.168.33.101/info.php に アクセス


## その他

* "レシピは上から順に実行されない"という話なので、php-gdのインストールとかがうまくいかないかもしれない。
* nodes|environments|data_bagsの使い分け、優先順位が今一わからない。
* ちょっと古い解説だと boxファイルを http://www.vagrantbox.es/ から入手するように書いてあるが、現在(バージョン1.8.1)ではhttps://atlas.hashicorp.com/boxes/search から探したほうが良い。
* もしかしたら CentOS 7 にPHP7をインストールするコミュニティレシピがあるのかも。
* vagrant up 後に chef-repo/nodes/sample.json が書き換えられてしまう。何故だかわからないので情報募集。
* 上で作ったVagrantfileとレシピ等は https://github.com/okadabasso/vagrant-centos-php7 にあります。