2013/02/17

CentOS 6.3にRails実行環境を構築する(Nginx+Rails+Unicorn+PostgreSQL)

はじめに

さくらのVPSのCentOS 6.3環境にRails実行環境を構築してみましたのでその手順まとめです。

Railsの実行環境は、production(本番運用環境)、test(本番環境と同等テスト実行環境)、development(開発環境)の3つがあります。一般的にproducution環境はApacheやNginxなどのWebサーバと連携して利用し、development環境はRailsに付属されているWEBrickというWebサーバを使ってローカル環境で動作確認するために使うことが良さそうですが、ここではNginx,Unicornも含めた開発環境のテスト構築のため、development環境のみにて環境構築をしています。

RailsはRubyで記述されたWebアプリケーションフレームワークです。MVC(Model/View/Controller)アーキテクチャに基づいて構築します。
RailsにおけるMVCアーキテクチャの概要については以下等が参考になるかと思います。

Railsアプリケーションを利用する上でRack対応httpサーバに何を選択するかは重要かと思いますが、ここではhttpサーバに最近主流になりつつあるUnicornを選択しています。

Unicorn単体でもRailsを動作させることができますが、一般的にはWebサーバとなるソフトウェア(Apache/Nignx等)をリバースプロキシとして利用して画像などの静的ファイルを処理させ、アプリケーションへのアクセスはUnicornへ渡し、Railsでの処理を行うのが一般的です。
NignxとUnicorn間の通信はUnix Domai SocketかTCPが用いることができますが、ここではUnix Domai Socketを利用することにしています。


なお、データベースにはSQLite、MySQL、PostgreSQLを選択することが可能で、デフォルトではSQLiteが選択されますが、ここではデータベースにはPostgreSQLを利用します。
NginxとPostgreSQLはRPMパッケージでインストールされているものとします。
また、Rubyはrbenv+ruby-buildでインストールされているものとします。

環境

インストール環境は以下です。

プラットフォーム
プラットフォーム さくらのVPS(SSD 1Gモデル)
OS CentOS 6.3 (x86_64)
利用するソフトウェア類
ミドルウェア バージョン 備考
Unicorn 4.5.0 httpサーバ
Nginx 1.2.6 CSS,JS,画像ファイル処理用リバースプロキシ(RPMインストール)
PostgreSQL 9.2.1 DBサーバ(RPMインストール)
Ruby 1.9.3-p374 Rubyプログラミング言語(rbenv管理)
RubyGems 1.8.23 Rubyのパッケージ/ライブラリ管理ツール
Rails 3.2.11 Ruby on Rails フレームワーク
その他環境補足情報
Railsアプリケーション用ルートディレクトリ /home/railsapp
Nginx待ち受けIP:ポート 0.0.0.0:80
Nginxログ出力先ディレクトリ /var/log/nginx
Unicorn(Rails)待ち受けIP:ポート 127.0.0.1:13000
Unicorn(Rails) Unix Domain Socket /var/run/unicorn/unicorn_railsapp.sock
Unicornログファイル出力先ディレクトリ /var/log/unicorn
Unicorn Pidファイル作成先ディレクトリ /var/run/unicorn

Rails実行環境構築

Railsのインストール

Railsをインストールします。
インストールはrootで行います。

$ su -
パスワード:

最初にgemを最新化します。

# gem update

Railsをインストールします。

# gem install rails

環境変数($PATH)の再読み込みします。

# source ~/.bashrc

Railsがインストールされていることを確認します。

# which rails
/usr/local/src/rbenv/shims/rails

bundlerのインストール

bundlerというRailsアプリケーション毎にgemパッケージ/ライブラリを独立して管理するためのツールをインストールします。

# gem install bundler
以上でRailsのインストールと設定は完了です。

# exit
新規Railsアプリケーション作成と初期設定

テスト用にrailsappという名前のRailsアプリケーションを作成します。
-dオプションでデータベースにPostgreSQLを指定します。--with-pg-configオプションにはpg_configのPATHを指定します。PostgreSQL 9.2のRPMパッケージでインストールした場合は/usr/pgsql-9.2/bin/pg_configとなっていると思います。
また、新規Railsアプリケーション作成(rails new実行)時、Gemfileに基づいたgemパッケージ/ライブラリ類のインストール(bundle install)が自動で実行されますが、Gemfileは後に編集するため、最初は--skip-bundleのオプションを指定して、bundle installを実行しないようにします。

$ cd /home
$ rails new railsapp -d postgresql --with-pg-config=/usr/pgsql-9.2/bin/pg_config --skip-bundle

database.ymlを編集し、Railsからのデータベースへの接続情報(ユーザ名,パスワード)を設定します。

$ cd /home/railsapp/config
$ vim database.yml
### 以下を修正
development:
  adapter: postgresql
  encoding: unicode
  database: railsapp_development
  pool: 5
  username: rails                 #<-Railsアプリ接続用のPostgreSQLユーザを設定
  password: rails                 #<-Railsアプリ接続用のPostgreSQLパスワードを設定

Gemfile内に必要なgemパッケージ/ライブラリを追記します。

$ cd /home/railsapp
$ vim Gemfile
…
gem 'pg'            # <- 利用するDB(ここではPostgreSQL)のgemパッケージ

gem 'execjs'        # <- javascriptランタイムライブラリ
gem 'therubyracer'  # <- javascriptランタイムライブラリ
…
gem 'haml-rails'    # <- hamlライブラリ
…
gem 'unicorn'       # <- Unicornライブラリ 
…

Gemfileを編集したらbundle installを実行し、Gemfileに記述されたパッケージ/ライブラリをインストールします。
このとき--pathオプションを指定することで、そのRailsアプリケーションの任意のディレクトリ配下にgemパッケージ/ライブラリ類をインストールできます($RAILS_ROOT/vendor/bundlerディレクトリにインストールするのが一般的です)。
これによりインストールしたgemパッケージ/ライブラリは、このRailsアプリケーションのみで利用可能な状態となり、他の環境に影響を与えません。

$ cd /home/railsapp
% bundle install --path vendor/bundle

これでRailsアプリケーションの作成は完了です。

PostgreSQLの設定

Railsアプリで利用するためのデータベースを作成します。 まず、PostgreSQLサーバにログインします。

$ psql -U postgres
psql (9.2.2)
"help" でヘルプを表示します.

postgres=# 

Rails接続用のユーザを作成します。

# CREATE USER rails WITH PASSWORD '************' CREATEDB CREATEUSER;
CREATE ROLE

Rails用のデータベースを作成します。

# CREATE DATABASE railsapp_development;
CREATE DATABASE
Unicornの設定

configディレクトリ配下にunicorn.rbというファイルを作成し、以下のような内容を記載します。

$ cd /home/railsapp/config
$ vim unicorn.rb
application = 'railsapp'

worker_processes 2
working_directory "/home/#{application}"

listen "/var/run/unicorn/unicorn_#{application}.sock"   # Unix Domain Socket

pid "/var/run/unicorn/unicorn_#{application}.pid"       # PIDファイル出力先
 
timeout 60
 
preload_app true

stdout_path "/var/log/unicorn/unicorn.stdout_#{application}.log"  # 標準出力ログ出力先
stderr_path "/var/log/unicorn/unicorn.stderr_#{application}.log"  # 標準エラー出力ログ出力先
 
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
 
before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid
      begin
        sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
        Process.kill(sig, File.read(old_pid).to_i)
      rescue Errno::ENOENT, Errno::ESRCH
      end
    end
 
    sleep 1
  end
 
after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

UnicornログファイルやPIDファイル用のディレクトリを作成します。

$ su -
パスワード:
# mkdir /var/log/unicorn
# chmod 777 /var/log/unicorn
# mkdir /var/run/unicorn
# chmod 777 /var/run/unicorn
Nginxの設定

Unicornと連携するためのNginxの設定ファイルを作成します。
デフォルトのnginx.confを編集したくないので、/etc/nginx/conf.d配下にnginxの設定ファイル(ここでは仮としてrails.conf)を新規に作成します。
前述のとおり、バックエンドのUnicornとの通信にはUnix Domain Socketを利用します。TCP通信を利用したい場合はproxy_passにTCPのものを適用してください。

$ su -
パスワード:
# cd /etc/nginx/conf.d
# vim rails.conf

    ### バックエンドのUnicornとの通信にはUnix Domain SocketかTCPのいずれかを利用
    ### ここではUnix Domain Socketを利用
    upstream unicorn-unix-domain-socket {
        ### unicorn.rbで指定したUnicornのソケットを指定:
        server unix:/var/run/unicorn/unicorn_railsapp.sock fail_timeout=0;
    }

    upstream unicorn-tcp {
        ### unicornのポートを指定 ※ここでは、Unicorn起動時にポート 13000で起動させるものとします。
        server 127.0.0.1:13000;
    }

    server {
        listen 80;
        server_name xxxxx.sakura.ne.jp;

        root /home/railsapp/public;

        access_log  /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        location / {
            if (-f $request_filename) {
                break;
            }

            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;

            proxy_pass http://unicorn-unix-domain-socket;      # unix domain socketを使う場合
            # proxy_pass http://unicorn-tcp;                   # tcpを使う場合
         }

         location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
            expires 1y;
         }
     }

デフォルトの設定ファイルが読み込まれないようにリネームしておきます。

# mv default.conf _default.conf_
Nginxを再起動(起動)します。
# service nginx restart
Stopping nginx:                                            [  OK  ]
Starting nginx:                                            [  OK  ]

確認

Unicornの起動

Nginxの設定ファイルに記述したとおりに、Unicornを使ってRailsをポート13000(-pオプション)を使ってデーモンモード(-Dオプション)としてバックグラウンドで起動させます。環境はdevelopment(-Eオプション)とします。

$ unicorn_rails -c /home/railsapp/config/unicorn.rb -E development -D -p 13000

さくらのVPS環境にブラウザからhttpでアクセスすると、以下のような画面が表示されると思います。

http://xxx.xxx.xxx.xxx # <- さくらのVPSのホストのIPアドレス

"About your application’s environment"を押下して、以下のようにRailsの環境情報が表示されればWebサーバやDBサーバとの連携が正常に行えていることになります。

おわりに

以上で、CentOS 6.3上でUnucornを使ったRails実行環境ができました。 Railsと合わせてUnicornやNginxについても勉強しながらもっと環境整備をできればと思います。 あとはCapistranoを使ってのデプロイ自動化も行っていきたいです。

0 Comments:

コメントを投稿