LoginSignup
8
5

More than 5 years have passed since last update.

NginxでRubyのCGIを動かす

Last updated at Posted at 2017-10-05

はじめに

NginxはCGIを標準では実行できませんが、FCGI Wrapを使うとCGIをFastCGIとして実行してくれます。

大昔に作ったRubyのCGIのアプリをNginxのサーバ上で動かしたかったので、FCGI Wrapを試してみました。

注意点として、FCGI WrapはFastCGIのインターフェースを提供してくれるだけなので、CGIと同様にユーザーから要求がある度に、プロセスの生成と破棄が行われるため、パフォーマンスは悪いみたいです。

環境

今回試した環境です。

  • Conoha VPS
  • Ubuntu 16.04.3 LTS (Xenial Xerus)
  • Nginx/1.10.3
  • Ruby 2.3.1p112 (2016-04-26)

タイトルにはRubyのCGIと書きましたが、設定のlocationの拡張子さえ変えれば、PerlやPythonやPHPなど他の言語でも同じように設定できると思います。

設定手順

FCGI Wrapの公式ページを参考にセットアップしました。

FCGI Wrapのインストール

sudo apt install fcgiwrap

設定

/etc/nginx/fcgiwrap.conf の作成

cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf

今回はRubyのCGIを動かしたかったので、以下のように修正しました。

diff --git a/usr/share/doc/fcgiwrap/examples/nginx.conf b/etc/nginx/fcgiwrap.conf
index 5bdfdf1..e218726 100644
--- a/usr/share/doc/fcgiwrap/examples/nginx.conf
+++ b/etc/nginx/fcgiwrap.conf
@@ -1,13 +1,13 @@
 # Include this file on your nginx.conf to support debian cgi-bin scripts using
 # fcgiwrap
-location /cgi-bin/ {
+location ~ .rb$ {
   # Disable gzip (it makes scripts feel slower since they have to complete
   # before getting gzipped)
   gzip off;

   # Set the root to /usr/lib (inside this location this means that we are
   # giving access to the files under /usr/lib/cgi-bin)
-  root /usr/lib;
+  #root /usr/lib;

   # Fastcgi socket
   fastcgi_pass  unix:/var/run/fcgiwrap.socket;
@@ -16,5 +16,5 @@ location /cgi-bin/ {
   include /etc/nginx/fastcgi_params;

   # Adjust non standard parameters (SCRIPT_FILENAME)
-  fastcgi_param SCRIPT_FILENAME  /usr/lib$fastcgi_script_name;
+  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 }

/etc/nginx/fcgiwrap.conf のインクルード

Nginxの設定ファイル構成によりますが、普通は /etc/nginx/sites-available/default の server ブロック内で読み込んでおけばいいと思います。

server {
+    # fast cgi support
+    include /etc/nginx/fcgiwrap.conf;
}

RubyのCGIスクリプト

まずは単純なスクリプトでテストしました。

適当な場所にパーミッションを正しく指定して配置してください。

#!/usr/bin/ruby

puts "Content-Type: text/html\n\n"
puts "<html>"
puts "<head><title>Test</title></head>"
puts "<body>"
puts "<h1>Hello CGI World!</h1>"
puts "</body>"
puts "</html>"

トラブルシューティング

躓いたポイントを紹介します。

SCRIPT_FILENAMEの設定

パーミッションは正しいのに403エラーとなってしまいました。

エラーログ /var/log/nginx/error.log を見ると以下のようになっていました。

2017/10/05 11:49:03 [error] 9728#9728: *45 FastCGI sent in stderr: “Cannot get script name, are DOCUMENT_ROOT and SCRIPT_NAME (or SCRIPT_FILENAME) set and is the script executable?” while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: _, request: “GET /app/test.rb HTTP/1.1", upstream: “fastcgi://unix:/var/run/fcgiwrap.socket:“, host: “xxx.xxx.xxx.xxx”

これは /etc/nginx/fcgiwrap.confSCRIPT_FILENAME を修正したら動きました。

-fastcgi_param SCRIPT_FILENAME  /usr/lib$fastcgi_script_name;
+fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

参考記事

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5