ubuntuにインストールしたnginxでCGIを動かしてみた。

ubuntuにインストールしたnginxでCGIを動かしてみました。もともとApacheで動いていたCGIスクリプトをnginxで動くようにしています。環境は以下です。作業はrootユーザーで行いました。

【環境】
ubuntu 18.04 LTS
nginx 1.16.1

まず、nginxでCGIを動かすためにはfcgiwrapが必要なのでインストールします。

fcgiwrapのインストール
# apt install fcgiwrap

パッケージのインストールができたらfcgiwrapを確認してみます。

インストールされたパッケージの確認
# dpkg -l | grep cgi

僕の環境では赤枠で囲ったパッケージがインストールされたようです。

[広告]

fcgiwrapの設定を確認します。fcgiwrapでは設定ファイルのようなものはないらしく、/etc/init.d配下にある起動スクリプトを確認します。

fcgiwrapの起動スクリプトの場所
/etc/init.d/fcgiwrap

この起動スクリプトに記載されている設定の中で確認する項目の抜粋(以下はデフォルト値)です。


 :
NAME="fcgiwrap"
 :
# FCGI_APP Variables
FCGI_CHILDREN="1"
FCGI_SOCKET="/var/run/$NAME.socket"
FCGI_USER="www-data"
FCGI_GROUP="www-data"

# Socket owner/group (will default to FCGI_USER/FCGI_GROUP if not defined)
FCGI_SOCKET_OWNER="www-data"
FCGI_SOCKET_GROUP="www-data"
 :

最初に、

NAME=”fcgiwrap”
FCGI_SOCKET=”/var/run/$NAME.socket”

ですが、これはnginxとfcgiwrapとのデータの受け渡しの方法です。nginxでは静的コンテンツしか処理できずCGIのような動的コンテンツはfcgiwrapが行うことになるのですが、CGIへのリクエストをnginxからfcgiwrapにどのような方法で受け渡すかを設定します。受け渡しの方法にはUnixソケットを使う方法とTCP/IPを使う方法があるのですが、デフォルトの設定ではUnixソケットを使う方法となっています。一般的にnginxとfcgiwrapを動かすサーバーが同一であればUnixソケットを使ったほうが効率がよいです。ですので、FCGI_SOCKETの設定はこのまま(デフォルトのまま)とします。

実際に、/var/run配下にfcgiwrap.socketがあるかどうか確認してみると以下のようにありました(緑線の部分、ピンク色線については後述)。

次に、

FCGI_CHILDREN=”1″

ですが、これはfcgiwrapがリクエストを待つ待機プロセスの数です。fcgiwrapはこの数分のプロセスを生成(C言語でいうfork)をしていて、リクエストが連続で来た際に待ちを作らずに並列に処理を裁ける数となります。本来はリクエスト数とサーバー性能を考慮してチューニングするべきですが、ここではいったんデフォルトのままとしておきます。

続いて、

FCGI_USER=”www-data”
FCGI_GROUP=”www-data”

ですが、これはfcgiwrapを実行するユーザー、および、グループを設定します。ここにはCGIスクリプトを実行できるユーザーを設定するのですが、ubuntuでApacheを動かす際は一般的にwww-dataを使用していて、今回はApacheで動かしていたCGIスクリプトをそのまま動かす想定なのでwww-dataのままとしておきます。

最後に、

FCGI_SOCKET_OWNER=”www-data”
FCGI_SOCKET_GROUP=”www-data”

ですが、これは先ほど記載したfcgiwrap.socketの所有者、および、グループの設定です。記載がなかった場合はFCGI_USER、FCGI_GROUPと同じになると起動スクリプトのコメントには記載されていました。こちらもデフォルトのwww-dataのままとしていたのですがfcgiwrap.socketの所有者、グループはrootになっていました(fcgiwrap.socketを確認した際のピンク色の線のところ)。ここのところの差異の理由は、ちょっとわかりませんでした。所有者はrootですが、www-dataでも読み書きできる権限となっているため問題ないのかもしれません。

fcgiwrapの設定の確認はここまでです。結果的にですが、fcgiwrapの設定は何も変えずにデフォルトのままで行きます。引き続き、nginxの設定に入ります。

[広告]

nginxの設定ファイルにCGIスクリプトへのリクエストがあった場合の動きを記載します。記載する設定ファイルはnginx.conf、もしくは、conf.d配下のconfファイルです。

nginxの設定ファイルの場所
/etc/nginx/nginx.conf
/etc/nginx/conf.d 配下のconfファイル

※nginx.confがconf.d配下のconfファイルを読み込んで(includeして)います。

記載する内容は以下です。serverディレクティブの中に記載してください。


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.socket;
}

この中で一番最後にあるfastcgi_passの設定が、nginxからfcgiwrapにUnixソケットを使用してデータを引き渡す、という設定になります。他の設定はパラメータファイルのインクルードとか404エラーファイルの出力などですが、細かい説明は省略します(すみません)。そのまま貼り付けてもらえれば動くはずです。。

上記を反映した僕の場合のserverディレクティブを載せておきます。

nginx.confにnginxを動かすユーザーが記載されているのですが、そのユーザーをnginxからwww-dataに変更しておきます。nginx.confの「user」という項目です。

変更前
user nginx;
 ↓
変更後
user www-data;

以上でnginxのconfファイルの修正は終了です。confファイルのテストを行います。

confファイルの確認
# nginx -t

「syntax is ok」および「test is successful」と表示されれば問題ありません。今回はfcgiwrapの設定は変えていないのでnginxの再起動のみ行います。

nginxの再起動
# systemctl restart nginx

nginxでCGIスクリプトにアクセスしてみてください。動くと思います。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です