CentOSにインストールしたnginxでCGIを動かしてみます。CGIはperlでサンプルプログラムを作ります。nginxでCGIを動かすにはfcgiwrapというパッケージが必要で、そのインストール作業からです。作業はrootユーザーで行います。
【環境】
・CentOS 7.9
・nginx 1.19.6
・perl 5.16.3
まず、インストールされるfcgiwrapを確認してみます。
# yum info fcgiwrap
バージョン1.1.0のものがあるようです。fcgiwrapをインストールします(インストールログの記載は省略します)。
# yum install fcgiwrap
インストールが終わった後の設定ですが /usr/share/doc/ 配下にfcgiwrapのSETUPの説明があるので、これを見てやってみます。
SETUPにはこのように書かれています。
Perform these steps after package installation: 1. Inspect the environment file /etc/sysconfig/fcgiwrap. Set fcgiwrap daemon parameters acording to your needs. See man fcgiwrap for details. 2. The systemd unit files provided with this package are instantiated and must be started by specifiying the desired web server user account. For example, when using nginx, the fgciwrap service is enabled then started like so: systemctl enable fcgiwrap@nginx.socket systemctl start fcgiwrap@nginx.socket Note the socket name is used here rather than the service name. There is no need to enable the service itself. Indeed one cannot enable the service on older versions of systemd. This is by design. See the systemd socket documentation for further details: https://www.freedesktop.org/software/systemd/man/systemd.socket.html
「1.」はパラメータの設定の記載です。パラメータの設定は /etc/sysconfig/fcgiwrap ファイルで行うようですがCGIを動かすだけならデフォルトのままでも大丈夫なのでそのままにします。
「2.」はfcgiwrapの起動に関する記載のようです。nginxはCGIのデータをファイルに書き込み、fcgiwrapはそのファイルを読み込むことでCGIのデータを取得します。この連携はソケットファイルで行います。nginxと連携するソケットファイルの作成はsystemctlコマンドで行い「fcgiwrap@」の後ろに起動ユーザー名を指定するようです。
とりあえず、やってみます。今回はnginxもfcgiwrapもnginxユーザーで動かします。ソケットファイルを作ります。
# systemctl start fcgiwrap@nginx.socket
SETUPでは「systemctl enable 〜」の記載もありますがCGIを動かしてみるだけなのでこれは省略します。ソケットファイルが実際に出来たか確認します。通常は /var/run 配下に出来ると思うのでそこを確認します。
/var/run 配下にfcgiwrapのディレクトリがあり、その下にnginxが所有者のソケットファイルが出来ていました。ソケットファイルが出来ているので、どうやらこれだけでfcgiwrapの準備は終わりのようです。あとはnginx側の設定です。
nginxではfcgiwrapに処理を引き渡す設定をdefault.confのserverディレクティブに記載します。default.confは /etc/nginx/conf.d 配下にあります。以下の記載をそのまま貼り付けてください。locationディレクティブに「〜.cgi」ファイルへのアクセスがあったときの処理を記載しています。太字部分がfcgiwrapのソケットファイルの指定になります。
location ~* \.cgi$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.cgi)(/.+)$; include fastcgi_params; fastcgi_index index.cgi; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_intercept_errors on; fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap-nginx.sock; }
実際のdefault.confはこのような感じです。
修正が出来たらnginxのコンフィグテストを行います。
# nginx -t
nginx.conf syntax is ok、nginx.conf test is successful、と表示されれば大丈夫です。nginx側の設定は以上です。
CGIが動くか確認するためにperlでサンプルプログラムを作ります。サンプルプログラムは以下のものです。1行目で指定しているperlの場所は環境に合わせてください。
#!/usr/bin/perl print "Content-Type: text/html\n\n"; print "<!DOCTYPE html>"; print "<html>"; print "<head><title>Test</title></head>"; print "<body>"; print "<h1>This is test page</h1>"; print "</body>"; print "</html>";
これをtest.cgiという名前でnginxのドキュメントルートに配置します。ドキュメントルートはdefault.confのrootディレクティブで指定しています。test.cgiには実行権限をつけてください。
ブラウザから http://nginxのIPアドレス/test.cgi でアクセスして、このような画面が表示されれば成功です。
fcgiwrapを止めるには以下のコマンドを使います。
# systemctl stop fcgiwrap@nginx.socket
これにより /var/run/fcgiwrap 配下のソケットファイルは削除されます。
ソケットファイルをnginx以外のユーザーで作成するには「fcgiwrap@」の後ろのユーザーを変えます。apacheユーザーの場合は、
# systemctl start fcgiwrap@apache.socket
となります。ソケットファイルの所有者を変える際はnginxの起動ユーザーも変更してください。nginxがソケットファイルにアクセスできないと「Permission denied」のエラーとなってしまいますので。
= = = = = = = = = =
後日談。。(追記しました)
数日後にfcgiwrapを起動してみたらエラーになりました。
# systemctl start fcgiwrap@nginx.socket Job for fcgiwrap@nginx.socket failed. See "systemctl status fcgiwrap@nginx.socket" and "journalctl -xe" for details.
systemctl status で見てみると「Socket service fcgiwrap@nginx.service already active, refusing.」とのこと。すでに有効になっていると言っているのですがソケットファイルはありません。systemctl stop 〜 をしてソケットファイルは削除されているのですが。。
仕方がないのでOS再起動をしてからfcgiwrapを起動したらソケットファイルが出来ました。推測になりますが systemctl stop 〜 をしてソケットファイルを消してもどこかに情報が残っているようです。SETUPの説明に systemctl enable 〜 と systemctl start 〜 の2つしか書かれていないのは停止の意味がない?からなのかもしれません。ですので、fcgiwrapはずっと起動したまま(ソケットファイルは作成したらそのまま)にしておきます。また、systemctl enable 〜 も実行しておきました。