nginx で CGI (Perl・Ruby・PHP) を動かす

Apache みたいな感じでサクッと動かせるのかと思ったら、nginx ではすんなり CGI が動かせないらしい。やり方を調べて、nginx 上で Perl・Ruby・PHP スクリプトが動かせるようになったので、手順を紹介する。

前提条件として、nginx はインストール済で、$ systemctl start nginx.service で起動できる状態とする。

目次

Perl と Ruby を動かす : fcgiwrap・spawn-fcgi

nginx で CGI を動かすには、fcgiwrap と spawn-fcgi というライブラリを利用する。

Oracle Linux 7 だと yum search してみたらパッケージが見つかったのでそのままインストールしてみた。CentOS とかで見つからない場合は適宜調べてなんとかせよ。

# Perl は最初から入っていたのでとりあえず良しとする
$ perl --version
This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi
(with 39 registered patches, see perl -V for more detail)

Copyright 1987-2012, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

# Ruby は Yum でサクッと入れておく。バージョン管理とかめんどいから無視
$ yum install -y ruby
$ ruby --version
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]

# fcgiwrap : spawn-fcgi との橋渡しをするラッパー
$ yum install -y fcgiwrap
$ which fcgiwrap
/sbin/fcgiwrap

# Perl・Ruby は spawn-fcgi で動かす
$ yum install -y spawn-fcgi fcgi-devel

続いて spawn-fcgi の設定ファイルを記述する。nginx ユーザが利用すること、9001番ポートで待機すること、などを書いている。先程 which コマンドで確認した fcgiwrap のフルパスも書く。

# 末尾に以下を追記する
OPTIONS="-u nginx -g nginx -a 127.0.0.1 -p 9001 -P /var/run/spawn-fcgi.pid -- /sbin/fcgiwrap"

そしたら spawn-fcgi を起動し、ステータスが active (running) になっていることを確認する。

$ systemctl start spawn-fcgi
$ systemctl status spawn-fcgi

$ lsof -i:9001 などとして、9001番ポートでリスンされていることを確認しておくと良いだろう。

spawn-fcgi の設定ができたら、nginx の設定ファイルを修正する。

server {
    listen       80;
    server_name  localhost;
    
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;
    
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    
    #error_page  404              /404.html;
    
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}
    
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}
    
    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

元はこんな状態だった。

PHP 向けの設定サンプルが記述されている部分を参考に、次のように記載する。includefastcgi_params; とだけ記述しても問題なさそう。

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    
    # For CGI : Perl Ruby
    location ~ \.(pl|rb|cgi)$ {
        try_files      $uri /404.html;
        root           /usr/share/nginx/html;
        fastcgi_pass   127.0.0.1:9001;
        fastcgi_index  index.cgi;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        /etc/nginx/fastcgi_params;
    }

設定ファイルを書き換えたら、nginx を再起動する。

$ systemctl restart nginx

nginx の準備ができたので、検証用の Perl・Ruby スクリプトを書く。ファイルには実行権限を付与しておくこと。

$ cd /usr/share/nginx/html/
$ touch example.pl
$ chmod 755 example.pl
$ touch example.rb
$ chmod 755 example.rb
#!/usr/bin/perl

print "Content-type: text/plain\n\n";
$my_var = 'Perl';
print "Hello World from $my_var .";
#!/usr/bin/ruby

print("Content-type: text/plain\n\n")
my_var = 'Ruby'
print("Hello World from #{my_var} .")

それぞれ

にアクセスして、Hello World 〜といった文言が出れば OK。

PHP を動かす : php-fpm

PHP だけは php-fpm というライブラリを使わないといけないらしいので、コレを使う。

# PHP の準備はサクッと Yum で
$ yum install -y php
$ php --version
PHP 5.4.16 (cli) (built: Oct 31 2019 11:43:39)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

# PHP は PHP-FPM で動かす
$ yum install -y php-fpm

# PHP-FPM を起動する
$ systemctl start php-fpm
$ systemctl status php-fpm

PHP-FPM の設定ファイルを修正する。

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
user = apache
; RPM: Keep a group allowed to write in log dir.
group = apache

デフォルトでは usergroupapache が記述されていると思うので、ココを nginx に書き換える。

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx

そしたら PHP-FPM を再起動する。

$ systemctl restart php-fpm

コレでデフォルトでは9000番ポートがリスンされていると思うので、念のため $ lsof -i:9000 などで確認しておく。

続いて nginx 設定ファイルに次のセクションを追加する。

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    
    # For CGI : Perl Ruby
    location ~ \.(pl|rb|cgi)$ {
        try_files      $uri /404.html;
        root           /usr/share/nginx/html;
        fastcgi_pass   127.0.0.1:9001;
        fastcgi_index  index.cgi;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        /etc/nginx/fastcgi_params;
    }
    
    # ↑ココまでは先程どおり・以下を追加する
    
    # For PHP
    location ~ \.php$ {
        try_files      $uri /404.html;
        root           /usr/share/nginx/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        /etc/nginx/fastcgi_params;
    }

Perl・Ruby 用の設定との違いは、9001番ポートではなく9000番ポートを指定しているだけ。

設定ファイルを書き換えたら nginx を再起動する。

$ systemctl restart nginx

検証用の PHP スクリプトを書く。ファイルには読み取り権限だけあれば良い (644)。

$ cd /usr/share/nginx/html/
$ touch example.php
<?php

phpinfo();

?>

コレで

にアクセスして PHP 情報が見えれば OK。

以上

結構仕組みを調べるのに手こずった…。

参考文献