RubyOnRailsとPHPを各複数バージョンで同時テストが可能な開発環境をAWSで作る(その3：PHP編)

# はじめに
## 動機
・RubyもPHPもバージョン差多すぎめんどくさい
・WebサーバはApacheばかり使ってたけどnginx使いたい。RubyもRaptor試してみたい
・設定する度に忘れてるから、毎度リセットしてる気がする。というかしてる、どうかしてる
## 目的
・RubyやPHP周りのバージョン差とかの検証をすぐにできる開発環境を整備する(とりあえずEC2で)
・サーバの初期設定やら何やらを記録しておく
## 完成形
EC2のmicro.t2に以下が乗った状態
・RHEL7
・nginx：1.6.2。PassengerやPHP-FPMへの振り分け
・Ruby：1.9.3-p551/2.0.0-p598/2.1.5をrbenvで切り替え
・Rails：3系/4系をアプリケーションごとに切り替え
・Passenger：5.0.0.beta1(Raptor)で、アプリケーションごとにRuby1.9系/2.0系/2.1系を切り替え
・PHP：5.3.29/5.4.35/5.5.19/5.6.3をphpenvで切り替え
・PHP-FPM：上記を同一ソースでドメインごとに切り替え
・MariaDB：5.5.40
## 想定読者
・EC2などでPHPやRubyOnRailsの開発用サーバを用意したい方
・LinuxサーバにSSHで繋いでコマンド叩いたりくらいはできる方
・物忘れの激しいWeb系の技術者(主に私)
## 記事内容
・ググったり推測したりで試してうまくいったら記録
・一応初期状態から上記の構成が完成するまでのほぼ全記録になるはず
・特別目新しいことがあるわけではない。たぶん
## お願い
・一応0から一式試したけど、バージョンなどによってはこの通りに行かないのでそのときはぐぐってください
・筆者はLinuxにあまり慣れているわけではありませんので、設定など、こうした方がいいというものがあったらご指摘ください
・~~コマンド打ってバージョン切り替えればいいじゃない~~まあそんなこといわずに
・~~Dockerでやれ~~そのため公開に迷ったのですが、導入コストが低いしせっかく書いたので載っけることにしました

この記事はその3：PHP編です。
その他の部分は、その1：基本設定編とその2：RubyOnRails編をご覧ください。

# PHPのインストール～nginxとの繋ぎ込み

## phpenv、php-build経由でPHPのインストール
[phpenv+php-build環境の構築と運用](http://d.hatena.ne.jp/hnw/20120828)
[phpenv + php-buildでPHPを複数バージョン利用する方法](http://liginc.co.jp/web/programming/php/126863)
主にこれらを用途に合わせて魔改造した結果を記述していく。
意外なところでこけてちょっと苦戦した。

PHPENV_ROOTを先に指定しておくとphpenvがそこにインストールされるので、まず先に指定を入れておく。

```
# vi /etc/profile.d/env.sh
```

以下の内容を記述(その1、その2の分も併せたものです)：

```
#rbenv
export RBENV_ROOT="/opt/rbenv"
PATH="$RBENV_ROOT/bin:$PATH"

#phpenv
export PHPENV_ROOT="/opt/phpenv"
PATH="$PATH:$PHPENV_ROOT/bin"

#nginx
PATH="$PATH:/opt/nginx/sbin"

export PATH
eval "$(rbenv init -)"
#eval "$(phpenv init -)"
```

phpenvとphp-buildのインストール。

```
# . /etc/profile.d/env.sh
# mkdir /root/src
# cd /root/src
# git clone https://github.com/CHH/phpenv.git
# cd phpenv/bin
# sh phpenv-install.sh
# mkdir /opt/phpenv/plugins
# cd /opt/phpenv/plugins
# git clone https://github.com/CHH/php-build.git
# vi /etc/profile.d/env.sh
```

対応行を変更(さっき末尾に入れたコメントを外す)：

```
eval "$(phpenv init -)"
```

これでphpenvコマンドが使用できるようになる。

```
# . /etc/profile.d/env.sh
# phpenv -v
rbenv 0.4.0-129-g7e0e85b
```

ってrbenvかーい。内部的にはrbenvらしいよ。

パッケージはとりあえず最低限で突っ込もうとしたが、エラー頻発で面倒になったのでまとめて投入することにしてしまった。
一部インストール済みもあるけど問題ないので気にしない。

```
# yum -y install libxml2-devel curl-devel libjpeg-devel libpng-devel readline-devel libtidy-devel libxslt-devel libmcrypt libmcrypt-devel libtool-ltdl-devel openssl-devel
```

最初はDevelopment Toolsでまとめてインストールしていなかったのでbzip2が入っていなくて、いきなりphp-buildから入れようとしたら、
./buildconf: No such file or directory
というエラーが出て、このときのファイルが残っているようでbzip2をインストール後に試しても同じ結果になった。
なお、/tmp/php-buildを消して再度実行したら解決した。

re2cはRHEL7だと記事執筆時点では上記で追加したリポジトリの何処にも入っていない。なんてこった。
rpmすらぱっと見では見当たらない。仕方ないのでさくっとソースから。

```
# cd /opt/src
# wget http://downloads.sourceforge.net/project/re2c/re2c/0.13.7.5/re2c-0.13.7.5.tar.gz
# tar xzvf re2c-0.13.7.5.tar.gz
# cd re2c-0.13.7.5
# ./configure
# make
# make install
```

ここからやっとPHPのインストール。
今回はFastCGI版をインストールするので、オプションはとりあえずfpmが含まれていてapxsが含まれていなければOK。まずはデフォルト値の確認。

```
# vi /opt/phpenv/plugins/php-build/share/php-build/default_configure_options
```

どっちも問題なかったので、細かいことは後で考えることにしてデフォルトでインストールすることにする。
これもgroupionstall前の話なのだが、ここでインストール試したら、エラーも出てないのにビルドがこけて悶絶。
どうやらXdebugあたりでこけているらしいが、調べてみたところ[こういうこと](http://hirobanex.net/article/2013/09/1379231000)らしい。インストールログを > /dev/null とか何なの……。
しかしinstall.shくらいは読むべきと言われるとぐうの音も出ない。

さてこれで準備が整ったのでインストール。

```
# phpenv install 5.6.3
(すごく時間かかる)
```

そんなこんなで無事ビルドできた。

```
# phpenv global 5.6.3
# php -v
PHP 5.6.3 (cli) (built: Dec 10 2014 14:31:34)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies
    with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
```

長く険しい戦いだった……でもこれインストールだけだし、しかもまだ途中だから。
ということで別バージョンを入れてみる。調子に乗って5.3系～5.5系を全部入れてみた。

```
# phpenv install 5.3.29
(すごく時間(
# phpenv install 5.4.35
(すごく(
# phpenv install 5.5.19
(
# phpenv versions
  system
  5.3.29
  5.4.35
  5.5.19
* 5.6.3 (set by /opt/phpenv/version)
# phpenv global 5.3.29
# php -v
PHP 5.3.29 (cli) (built: Nov 24 2014 11:17:04)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
    with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
# php global 5.6.3
# php -v
PHP 5.6.3 (cli) (built: Dec 10 2014 14:31:34)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies
    with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
```

いい感じじゃない。

## 複数バージョンのphp-fpmをnginxと繋ぎ込み
RHEL7でのphp-fpm複数自動起動は先人の知恵が通用しなかった(ぱっと見では見つからなかった)ため、自分で作ることになった。
php-fpmの設定については、[php-buildで複数バージョンのPHP-FPMを用意する](http://d.hatena.ne.jp/hnw/20130626)をほぼそのまま使った。

```
cd /etc/systemd/system
vi php-5.6.3-fpm.service
```

以下の内容を記載。

```
[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target

[Service]
Type=notify
PIDFile=/usr/local/phpenv/versions/5.6.3/var/run/php-fpm.pid
TimeoutStartSec=0
ExecStart=/usr/local/phpenv/versions/5.6.3/sbin/php-fpm --daemonize
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

書いたら次はphp.iniとphp-fpm.confを設定。

```
# cd /opt/phpenv/versions/5.6.3/etc
# cp -p php-fpm.conf.default php-fpm.conf
# vi php.ini
```

対応行を変更：

```
display_errors = On
date.timezone = Asia/Tokyo
```

```
# vi php-fpm.conf
```

対応行を変更：

```
pid = run/php-fpm.pid
user = nginx
group = www
listen = 127.0.0.1:56000
listen.allowed_clients = 127.0.0.1
```

これで準備完了。

```
# systemctl start php-5.6.3-fpm
```

これでエラーが起きなければ起動には成功しているはず。
エラーも出ないけど帰ってこない……Ctrl+Cで抜け出した。ps aux | grep phpしたら生きてたので気にしないことにしよう。
上記の回避方法については、今後の課題とする。

```
# systemctl enable php5.6.3-fpm
```

こっちはうまくいったようだ。
再起動してプロセスが立ち上がっていればOK。

これをそれぞれのバージョンに対して行う。

あとは最後にnginx.confを調整。

```
# vi /opt/nginx/conf/nginx.conf
```

末尾の}の直前に以下を記載。
ログばらばらにしないなら、ドメイン名に正規表現使ってまとめて指定できると思う。
うまくまとめる方法がございましたらご教授ください。

```
    server {
        listen 80;
        server_name php56.yourdomain;
        root /var/www/php/;
        access_log /var/log/php56_access.log;
        error_log /var/log/php56_error.log;
        index index.php index.html index.htm;
        location ~ \.php.*$ {
            fastcgi_split_path_info ^(.+\.php)(.*)$;
            fastcgi_pass 127.0.0.1:56000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            include fastcgi_params;
        }
    }
    server {
        listen 80;
        server_name php55.yourdomain;
        root /var/www/php/;
        access_log /var/log/php55_access.log;
        error_log /var/log/php55_error.log;
        index index.php index.html index.htm;
        location ~ \.php.*$ {
            fastcgi_split_path_info ^(.+\.php)(.*)$;
            fastcgi_pass 127.0.0.1:55000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            include fastcgi_params;
        }
    }
    server {
        listen 80;
        server_name php54.yourdomain;
        root /var/www/php/;
        access_log /var/log/php54_access.log;
        error_log /var/log/php54_error.log;
        index index.php index.html index.htm;
        location ~ \.php.*$ {
            fastcgi_split_path_info ^(.+\.php)(.*)$;
            fastcgi_pass 127.0.0.1:54000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            include fastcgi_params;
        }
    }
    server {
        listen 80;
        server_name php53.yourdomain;
        root /var/www/php/;
        access_log /var/log/php53_access.log;
        error_log /var/log/php53_error.log;
        index index.php index.html index.htm;
        location ~ \.php.*$ {
            fastcgi_split_path_info ^(.+\.php)(.*)$;
            fastcgi_pass 127.0.0.1:53000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            include fastcgi_params;
        }
    }
```

ドメインは取得済みのものを使うか、適当なものを振ってそれをアクセス元のhostsファイルに書いておく。
ドキュメントルートは適当に変更して、index.phpを設置しておく。中身はphpinfo()なので省略。

```
# mkdir /var/www/php
# vi /var/www/php/index.php
# chown -R nginx:www /var/www
```

一応設定をテスト後、nginxを再起動。

```
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl restart nginx
```

php53～php56のサブドメインのそれぞれで開くと、それぞれのバージョンでのphpinfo()が出力される。


以上で本記事は終了となります。
有益な情報を公開しておられる先人の方々に感謝します。