明滅するプログラマの思索

WEBエンジニアとして勤務している一介の男が、日々気づいたことをまとめるブログです

Nginx のリバースプロキシを利用し PHP 処理を Apache で行う

Nginx のシェアが堅調に伸びているようです。
Apache と違い、静的なコンテンツを大量にさばくのに適した Web サーバですが、サーバサイドスクリプトを実行する場合はちょっとしたテクニックが必要となります。
PHP の場合、php-fpm を起動し UNIXドメインソケット経由で実行させる方法があります。
この方法の場合、ファイルベースでセッションを管理しようとすると、格納先(デフォルトだと /var/lib/php/session)のアクセス権をフルオープンにしなくてはならず、個人的には好きな方法ではありません。
やはり PHPApache モジュールにさばいてもらうのが、今までの前提知識も崩れにくく、安定すると思います。
そこで、Web フロントは Nginx に立ってもらい、PHPリクエストの場合は Apache に流して実行する、という構築を行ってみたいと思います。

導入環境

ソフトウェア バージョン
CentOS 7.3
Nginx 1.12.1
Apache 2.4.6

Apache 設定

今回は Nginx フロントは80番ポート、そこから Apache へ処理を流す際は8001番ポートとして実装してみます。
また、<example.jp> は任意のドメインです。
Apache と Nginx は同じサーバ上で稼働するものとします。
まずは Apache の設定から。

vi /etc/httpd/conf/httpd.conf

httpd.conf を編集して、80番を受け取らないようにします。

#Listen 80
Listen 8001

バーチャルホストを切ります。

vi /etc/httpd/conf.d/virtualhost.conf

以下を追記します。

<VirtualHost 127.0.0.1:8001>
    ServerName <example.jp>
    DocumentRoot <example>/htdocs
    <Directory "<example>/htdocs">
        DirectoryIndex index.php
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

Apache を再起動しておきます。

systemctl reload httpd

Nginx インストール

Nginx をインストールします。

rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum -y update nginx-release-centos
yum -y --enablerepo=nginx install nginx

Nginx でバーチャルホストを切ります。

vi /etc/nginx/conf/default.conf

以下を追記します。

server {
    listen       80;
    server_name  <example.jp>;
    charset UTF-8;

    access_log  /var/log/nginx/<example>/access.log  main;
    error_log   /var/log/nginx/<example>/error.log warn;

    root <example>/htdocs;
    index index.php index.html index.htm;

    proxy_max_temp_file_size 0;
    expires -1;
    real_ip_header X-Forwarded-For;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~* .*\.php$ {
        proxy_set_header  X-Real-IP       $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  Host            $http_host;
        proxy_pass http://127.0.0.1:8001;
    }
}

上記の設定により、リクエスURIのファイルが .php で終わる場合、リバースプロキシを利用して同じサーバの8001番ポートにリクエストを行います。

次にログディレクトリを作成します。
今回は /var/log の下に nginx 用のログディレクトリを切ります。

mkdir /var/log/nginx/<example>
chown nginx. /var/log/nginx/<example>

Apache の rotatelogs のようなツールは存在しないので、logrotate を利用します。

vi /etc/logrotate.d/nginx

以下を追記します。

/var/log/nginx/*/*log {
 dateext
 rotate 365
 missingok
 postrotate
     /bin/kill -USR1 `/bin/cat /var/run/nginx.pid 2>/dev/null` 2>/dev/null || true
 endscript
}

設定ファイルのチェックをして、

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

Nginx を起動します。

systemctl start nginx

これで<example.jp> にアクセスしたとき、PHPが実行された場合は apache経由となり、そうでない場合は Nginx が処理を行うようになります。