からくりがてんこ

IT関連情報、プログラミングに関する作業ログや備忘録を記載していきます。

さくらレンタルサーバ(スタンダード)でRails4を動かす

さくらレンタルサーバー(スタンダード)にRailsを入れるってとこは前回やりました。
この類の内容は情報古めですが、たくさんありますね。
でも肝心なのは動かすってことです。

今回はRailsを動かすってことをやります。

まず、前提として共有サーバは常駐プロセスの起動を禁止しています。

RailsWEBrickを使って起動する場合

$ rails server

ってやって3000番ポートで常駐プロセスを立ち上げて
"http://localhost:3000"に接続して起動確認してましたね。

ん?常駐プロセスだから無理じゃん!?
と思ったのですが、CGIで動かすことで実現できるようです。

先に言っておきます。CGIで動かしてもパフォーマンスがめっちゃ悪いため使い物になりません。
FastCGIという選択肢もあるのですが、さくらは対応してない。。

cgiの特徴

- apacheがリクエストを受け、別のプロセスで実行される
- 速度が遅い(プロセスの生成&破棄で時間がかかる)
- 共有サーバなどで利用される

常駐プロセスでなく、リクエストの度にプロセスを立ち上げてRailsを呼び出すってことですね。
たしかにこれなら動かせそうだ。

流れ

1. (rails)/app/public/配下に「.htaccess」と「dispatch.cgi」を作成します。
2. 各種パスを設定&railsのアクセスURLにサブディレクト対応する
3. ApacheRailsシンボリックリンクでつなぐ

下準備

Railsアプリを作る
$ mkdir ~/rails
$ cd ~/rails
$ rails new hoge

Gem::RemoteFetcher::FetchError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

何かエラーが出ました。
どうやら、gemの取得先がHTTPSでなくHTTPでないとダメみたいですね。(それもちょっち気持ち悪い)
$ vi Gemfile
ーーーー
source 'https://rubygems.org'

source 'http://rubygems.org'
ーーーー

次は、sqliteで引っかかりました。

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

/home/(ユーザー名)/local/rbenv/versions/2.1.5/bin/ruby extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'port install sqlite3 +universal',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
and check your shared library search path (the
location where your sqlite3 shared library is located).

extconf.rb failed ***

Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.

Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/home/(ユーザー名)/local/rbenv/versions/2.1.5/bin/ruby
--with-sqlite3-dir
--without-sqlite3-dir
--with-sqlite3-include
--without-sqlite3-include=${sqlite3-dir}/include
--with-sqlite3-lib
--without-sqlite3-lib=${sqlite3-dir}/lib

extconf failed, exit code 1

Gem files will remain installed in /home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/sqlite3-1.3.10 for inspection.
Results logged to /home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/extensions/x86_64-freebsd-9/2.1.0-static/sqlite3-1.3.10/gem_make.out
An error occurred while installing sqlite3 (1.3.10), and Bundler cannot continue.
Make sure that `gem install sqlite3 -v '1.3.10'` succeeds before bundling.

sqlite3をインストールせよと言われたからには、sqlite3をインストールしましょう
でも、そのままコマンド叩いてもうまくいかなかったので、一旦wgetで持ってきて入れることで解消しました。

$ cd ~/local/src/
$ wget http://www.sqlite.org/sqlite-amalgamation-3.6.23.1.tar.gz
$ tar vxzf sqlite-amalgamation-3.6.23.1.tar.gz
$ cd sqlite-3.6.23.1
$ ./configure --prefix=$HOME/local
$ make
$ make install
$ gem install sqlite3-ruby -- --with-sqlite3-dir=$HOME/local

※prefixの場所は個々の場所を記載してください。


fcgiをインストールしましょう

$ cd ~/local/src
$ wget http://www.fastcgi.com/dist/fcgi-2.4.0.tar.gz
$ tar xzvf fcgi-2.4.0.tar.gz
$ cd fcgi-2.4.0
$ ./configure --prefix=$HOME/local
$ ./configure --prefix=$HOME/local CFLAGS="-g -O2 -Wall -fPIC" CXXFLAGS="-g -O2 -Wall -fPIC"
$ make
$ make install
$ gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib

CGI使うからこれいらない?!)

適当にアプリも作っておきましょう

$ cd ~/rails
$ rails g scaffold test name:string
$ rake db:migrate

名前を登録・編集・削除できるといった内容です。
scaffoldは便利!!

ちょっと長くなりましたが下準備完了

(rails)/app/public/配下に「.htaccess」と「dispatch.cgi」を作成します。

お題の通り下記ファイルを配置します

.htaccess
RewriteEngine On
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
 
ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"
dispatch.cgi
#!/home/(ユーザー名)/local/rbenv/versions/2.1.5/bin/ruby

require File.dirname(__FILE__) + '/../config/boot'
require File.dirname(__FILE__) + '/../config/environment'

class Rack::PathInfoRewriter
  def initialize(app)
    @app = app
  end
  def call(env)
    env.delete('SCRIPT_NAME')
    parts = env['REQUEST_URI'].split('?')
    env['PATH_INFO'] = parts[0]
    env['QUERY_STRING'] = parts[1].to_s
    env['PATH_INFO'] = env['PATH_INFO'].gsub(/\A#{ENV['RAILS_RELATIVE_URL_ROOT']}(.*)\Z/, '\1')
    env['SCRIPT_NAME'] = ENV['RAILS_RELATIVE_URL_ROOT']
    @app.call(env)
  end
end
Rack::Handler::CGI.run  Rack::PathInfoRewriter.new(Hoge::Application)

各種パスを設定&railsのアクセスURLにサブディレクト対応する

「boot.rb」「environment.rb」「config.ru」を設定します。

boot.rb
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
 
$LOAD_PATH.push('/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby/2.1.0')
$LOAD_PATH.push('/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby/site_ruby/2.1.0')
$LOAD_PATH.push('/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby/gems/2.1.0')
$LOAD_PATH.push('/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby')
$LOAD_PATH.push('/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib')
 
ENV['PATH'] += ':/home/(ユーザー名)/local/bin'
 
 
ENV['GEM_HOME'] ||= '/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby/gems/2.1.0'
 
ENV['RAILS_RELATIVE_URL_ROOT'] = '/hoge'
config/environment.rb
# Load the Rails application.
require File.expand_path('../application', __FILE__)

# Initialize the Rails application.
Rails.application.initialize!
 
$LOAD_PATH.push("/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/")
$LOAD_PATH.push("/home/(ユーザー名)/local/rbenv/versions/2.1.5/lib/ruby")
ENV['GEM_HOME'] ||= '/home/(ユーザー名)/local/rbenv/versions/2.1.5/bin/gem'
 
ENV['RAILS_RELATIVE_URL_ROOT']="/hoge"
config.ru
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment',  __FILE__)
map ActionController::Base.config.relative_url_root || "/" do 
run Rails.application
end

ApacheRailsシンボリックリンクでつなぐ

シンボリックリンク作成

$ ln -s ~/rails/hoge/public ~/www/hoge

ブラウザで確認してみよう!!

http://(ユーザー名).sakura.ne.jp/hoge/tests

OK!

処理の流れ

  1. Apacheがリクエストを受け/hogeは~/www/hogeだよと解釈
  2. ~/www/hogeシンボリックリンクになっていて、~/rails/hoge/publicの.htaccessに処理が渡る
  3. .htaccessでdispatch.cgiに処理が渡り、Railsが呼び出される

このようになってると思われ。

できたけど、遅すぎて使えないのでなんか消化不良。。

感謝サイト:
http://takuya-1st.hatenablog.jp/entry/20120108/1326034652
http://d.hatena.ne.jp/iishun/20120423/1335200728
http://d.hatena.ne.jp/aTaGo/20100708/1278608962
http://d.hatena.ne.jp/replication/20090323/1237735348
http://zaya3.blog.fc2.com/blog-entry-50.html