CentOS に Ruby をインストールして Apache で CGI として実行できるようにする

以前、GCE (Google Compute Engine) に Apache をインストールして、Web サーバを公開した。

今回はこの環境をベースに、Apache インストール済の CentOS 7 に Ruby をインストールし、Apache 上で Ruby を CGI として動作させられるようにしてみる。

目次

rbenv を使ってみる (上手くいかなくて断念した)

まずは CentOS に Ruby をインストールしていく。Ruby は $ yum install ruby でもインストールできるが、バージョンが v2.0.0 と少し古めなので、rbenv を使ってインストールしてみる。

以降やったことを書いていくが、結論から書くとどうも rbenv install 時のエラーが解消できなくで諦めたので、参考程度に。

rbenv をインストールする

以降の手順は全て root ユーザで実施している。

# Git がなければ入れておく
$ yum install -y git

# rbenv を設定する
$ git clone https://github.com/rbenv/rbenv.git "${HOME}/.rbenv"
$ cd "${HOME}/.rbenv"
$ src/configure
$ make -C src
$ echo 'export PATH="${HOME}/.rbenv/bin:${PATH}"' >> "${HOME}/.bash_profile"
$ echo 'eval "$(rbenv init -)"' >> "${HOME}/.bash_profile"

# 最後に再読み込み
$ source "${HOME}/.bash_profile"
# 「rbenv は関数です」と表示されれば OK
$ type rbenv

ruby-build をインストールする

rbenv install コマンドを叩けるようにするため、ruby-build プラグインをインストールしておく。

$ git clone https://github.com/rbenv/ruby-build.git "${HOME}/.rbenv/plugins/ruby-build"
$ "${HOME}/.rbenv/plugins/ruby-build/install.sh"

rbenv で Ruby をインストールする

# インストールに必要なパッケージを先にインストールしておく
$ yum install -y bzip2 gcc gcc-c++ openssl-devel readline-devel zlib-devel

# インストール可能なバージョンを確認する
$ rbenv install -l

# 現時点で最新安定版の 2.6.5 をインストールする
$ rbenv install --verbose 2.6.5

# ↑が上手くいけば、以下のように設定していく…

# グローバルで利用する Ruby として設定する
$ rbenv global 2.6.5

# バージョン確認する
$ ruby -v

$ rbenv install 2.6.5 コマンドに --verbose を付けておくと進捗が分かる (付けないと Installing ruby-2.6.5... のあとしばらく待たされて不安になるw)。

rbenv install コマンドはソースからビルドしているので、とにかく時間がかかる。BUILD FAILED エラーが出た場合は Yum で必要なパッケージをインストールできているか要確認。

結局上手く行かなかった

 95% [1044/1093]  parse.y
make: *** [rdoc] 強制終了

BUILD FAILED (CentOS Linux 7 using ruby-build 20191205-4-gf04eb99)

Inspect or clean up the working tree at /tmp/ruby-build.20191223140436.21245.BAWEaU
Results logged to /tmp/ruby-build.20191223140436.21245.log

Last 10 log lines:
 94% [1036/1093]  mjit.c
 94% [1037/1093]  mjit_compile.c
 94% [1038/1093]  mjit_worker.c
 95% [1039/1093]  node.c
 95% [1040/1093]  numeric.c
 95% [1041/1093]  object.c
 95% [1042/1093]  pack.c
 95% [1043/1093]  parse.c
 95% [1044/1093]  parse.y
make: *** [rdoc] 強制終了

このようなエラーがどうにも解消できなくて、上手くいかないから止めた。

# インストールしかけたファイルを全部消す
$ rm -rf "${HOME}/.rbenv"
$ rm -rf /tmp/ruby-build*

# 追記した文言を消す
$ vi "${HOME}/.bash_profile"

RPM で Ruby をインストールする

rbenv を使ってソースからビルドしていくのはどうも失敗してしまったので、ビルド済のパッケージをインストールできないか探してみた。すると、以下で RPM が配布されていたので、コレを使ってみる。

$ yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.5/ruby-2.6.5-1.el7.centos.x86_64.rpm

$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]

コチラはすんなり上手くインストールできた。時間もかからないし、rbenv で複数バージョン管理したいこともそうそうないし、今後ともコレでいいかな。

Apache の設定を変更して Ruby CGI が動作するようにする

前回の記事で次のような Apache がインストール済だ。

$ httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Aug  8 2019 11:41:18

Apache の設定ファイルを次のように修正し、Ruby CGI が動作するようにしていく。

$ vi /etc/httpd/conf/httpd.conf

# ↓131行 : ルートディレクトリ
<Directory "/var/www/html">
  # ↓144行 : ExecCGI を追加し CGI の実行を許可する
  Options Indexes FollowSymLinks ExecCGI
  
  # ↓151行 : .htaccess で使用できるディレクティブを設定する。None から All に変えて .htaccess の設定が効くようにしておく
  AllowOverride All

# ↓261行
<IfModule mime_module>
  # ↓294行 : コメントアウトされているのをアンコメントして「.rb」を追加する
  AddHandler cgi-script .cgi .rb

設定変更したら、以下のコマンドで再起動する。

$ systemctl restart httpd

動作確認のため、次のような Ruby スクリプトを用意する。

#!/usr/bin/ruby

print("content-type: text/html\n\n")
print("<title>Hello World</title>\n")
print("<p><strong>Hello World</strong></p>\n")

改行コード \n を展開させるために、シングルクォートではなくダブルクォートを使う。

ブラウザで check.rb ファイルにアクセスすると Internal Server Error になった。ログを見てみる。

$ vi /var/log/httpd/error_log

1 [Mon Dec 23 14:43:06.604584 2019] [cgi:error] [pid 6163] [client 210.138.100.192:52667] AH01215: (13)Permission denied: exec of '/var/www/html/check.rb' failed
 12 [Mon Dec 23 14:43:06.604650 2019] [cgi:error] [pid 6163] [client 210.138.100.192:52667] End of script output before headers: check.rb

Permission denied となっているので、ファイルの実行権限がないっぽい。というワケでファイルに実行権限をつける。

$ chmod 777 /var/www/html/check.rb

コレで動いた。

なお、$ which ruby の結果は /bin/ruby だったが、Shebang は #!/usr/bin/ruby でも大丈夫だった (/usr/bin/ruby も存在するので)。

以下は一応見たが直接採用しなかった。

以上

Rails の場合は Passenger というモジュールを使ったりするようだが、単純な Ruby スクリプトを CGI として動作させる場合は、こんな感じで済んだ。