【PHPバージョン共存】特定のバーチャルドメインのみPHPをバージョンアップする

Apachephp環境の複数のバーチャルドメインを運用されている環境で、特定のバーチャルドメインだけPHPのバージョンアップをしたいという相談を受ける機会があったので検証してみました。 php-fpmを利用してバーチャルドメインごとにphp-fpmのソケットを別にして稼働中の環境はさほど困ることはないかと思いますが、モジュール版でphpを稼働している環境は大変かなと思いましたので、モジュール版からphp-fpm(FastCGI版)へ変更するところ含めて記載します。

前提

以下の環境において、PHPをモジュール版からphp-fpm(Fast CGI)に変更し、「sub2.tekunote.com」のみPHP7.3へ変更します。「sub1.tekunote.com」はPHP5.4のままとします。なお、PHPyumで導入することとします。 ◆前提構成概要

項目 内容
OS CentOS Linux release 7.8
PHP 5.4 (baseリポジトリ)、モジュール版で稼働
PHPモジュール版用設定先 /etc/httpd/conf.d/php.conf
バーチャルドメイン sub1.tekunote.com,sub2.tekunote.com

◆前提バーチャル設定詳細

<VirtualHost *:80>
  ServerName sub1.tekunote.com
  ServerAdmin root@localhost
  DocumentRoot /var/www/vhosts/sub1.tekunote.com/WWW
  ErrorLog /var/www/vhosts/sub1.tekunote.com/LOG/httpd/error_log
  CustomLog /var/www/vhosts/sub1.tekunote.com/LOG/httpd/access_log   combined
</VirtualHost>

<VirtualHost *:80>
  ServerName sub2.tekunote.com
  ServerAdmin root@localhost
  DocumentRoot /var/www/vhosts/sub2.tekunote.com/WWW
  ErrorLog /var/www/vhosts/sub2.tekunote.com/LOG/httpd/error_log
  CustomLog /var/www/vhosts/sub2.tekunote.com/LOG/httpd/access_log   combined
</VirtualHost>

やってみた

php-fpm(5.4 base)のインストール

// インストール
$ sudo yum install --enablerepo=base php-fpm

// php-fpm自動起動
$ systemctl enable php-fpm.service

php73,php73-php-fpm(7.3 remi)のインストール

// remiリポジトリのインストール
$ yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

// php73,php73-php-fpmのインストール
$ yum install --enablerepo=remi-php73 php73 php73-php-fpm

// php73-php-fpm自動起動
$ systemctl enable php73-php-fpm.service

php-fpm,php73-php-fpmデフォルト設定の退避

// 5.4系
$ cd /etc/php-fpm.d/
$ mv www.conf www.conf_org

// 7.3系
$ cd /etc/opt/remi/php73/php-fpm.d/
$ mv www.conf www.conf_org

php-fpmの設定ファイルの作成

以下の通り、sub1.tekunote.com、sub2.tekunote.comの設定を作成します。 作成先はOS標準の5.4系は/etc/php-fpm.d/、remiの7.3系は/etc/opt/remi/php73/php-fpm.d/となります。 ◆sub1.tekunote.com用(5.4) /etc/php-fpm.d/sub1.tekunote.com.conf

[sub1.tekunote.com]

listen = /var/run/php-fpm/sub1.tekunote.com.sock
listen.allowed_clients = 127.0.0.1
listen.owner = apache
listen.group = apache
listen.mode = 0666

user = apache
group = apache

pm = ondemand
pm.max_children = 50
pm.max_requests = 1000

slowlog = /var/www/vhosts/sub1.tekunote.com/LOG/php-fpm/sub1.tekunote.com-slow.log

php_admin_value[error_log] = /var/www/vhosts/sub1.tekunote.com/LOG/php-fpm/sub1.tekunote.com-error.log
php_admin_flag[log_errors] = on

php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session

◆sub2.tekunote.com用(7.3) /etc/opt/remi/php73/php-fpm.d/sub2.tekunote.com.conf

[sub2.tekunote.com]

listen = /var/run/php-fpm/sub2.tekunote.com.sock
listen.allowed_clients = 127.0.0.1
listen.owner = apache
listen.group = apache
listen.mode = 0666

user = apache
group = apache

pm = ondemand
pm.max_children = 50
pm.max_requests = 1000

slowlog = /var/www/vhosts/sub2.tekunote.com/LOG/php-fpm/sub2.tekunote.com-slow.log

php_admin_value[error_log] = /var/www/vhosts/sub2.tekunote.com/LOG/php-fpm/sub2.tekunote.com-error.log
php_admin_flag[log_errors] = on

php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session

ポイントはlisten = ソケット名です。listenでバーチャルドメインごとに異なるソケットを指定することで、対応するバージョンへの接続を振り分けることができます。また、今回はソケットを採用しましたがSetHandler "proxy:fcgi://127.0.0.1:ポート番号"のようにポート番号を個別に割り当てることでも振り分けができます。子プロセスの制御については、複数のドメインを1サーバに搭載する場合、子プロセスを必要に応じて立ち上げるpm = ondemandが不要なリソースを抑えられるという判断で、ここではそのように設定しています。その他の設定についても必要最低限を記載していますので、環境に合わせて適宜修正ください。php-fpmの設定については下記をご参考ください。 ◆php-fpm設定の参考サイト PHP: 設定 - Manual

apacheのモジュール版設定の削除

$ cd /etc/httpd/conf.d
$ mv php.conf php.conf_org

phpインストール時のデフォルトでは上記のファイルでモジュール版用の設定がされています。もし、個別に設定している場合は、該当の設定を削除してください。php.confの説明は割愛しますが、DirectoryIndex index.phpが必要な方は、この設定だけ残すか、移動させましょう。

apachephp-fpm,php73-php-fpmの連携

以下のようにバーチャルドメインの設定を行います。FilesMatchディレクティブで囲まれたところが追記する個所です。

<VirtualHost *:80>
  ServerName sub1.tekunote.com
  ServerAdmin root@localhost
  DocumentRoot /var/www/vhosts/sub1.tekunote.com/WWW
  ErrorLog /var/www/vhosts/sub1.tekunote.com/LOG/httpd/error_log
  CustomLog /var/www/vhosts/sub1.tekunote.com/LOG/httpd/access_log   combined

  # php-fpm
  <FilesMatch \.php
 
gt; SetHandler "proxy:unix:/run/php-fpm/sub1.tekunote.com.sock|fcgi://localhost" </FilesMatch> </VirtualHost> <VirtualHost *:80> ServerName sub2.tekunote.com ServerAdmin root@localhost DocumentRoot /var/www/vhosts/sub2.tekunote.com/WWW ErrorLog /var/www/vhosts/sub2.tekunote.com/LOG/httpd/error_log CustomLog /var/www/vhosts/sub2.tekunote.com/LOG/httpd/access_log combined # php73-php-fpm <FilesMatch \.php
 
gt; SetHandler "proxy:unix:/run/php-fpm/sub2.tekunote.com.sock|fcgi://localhost" </FilesMatch> </VirtualHost>

php-fpm,php73-php-fpmの起動とapacheの設定反映

$ systemctl start php-fpm.service
$ systemctl start php73-php-fpm.service
$ systemctl reload httpd.service

動作確認

phpinfoで各バーチャルドメインPHPバージョンの確認と、php-fpmで動作していることの確認を行いました。結果は以下の通りです。php-fpmで動作していることはServer APIの項目でFPM/FastCGIとなっていることで確認できます。もし、モジュール版で動作している際はApache 2.0 Handlerと表示されます。 ◆sub1.tekunoto.com ◆sub2.tekunoto.com

最後に

PHPドメイン個別のバージョンアップの要望に柔軟に対応できそうです。また、Plesk等のサーバ管理ツールでは、ドメインごとにPHPのバージョンを容易に管理できますが、スケールアウトやパフォーマンスのチューニングのことを考えるとサーバ管理ツールを利用することがネックとなる場合もあるかと思います。そういったところからの移行の時にも便利だなと思いました。