Ruby on Rails
Ruby on Rails (よく Rails とか RoR と略されます) は Ruby プログラミング言語によるオープンソースのウェブアプリケーションフレームワークです。Rails はウェブ開発者によって高速な開発のために使用されているアジャイル開発で使われるように出来ています。
このドキュメントでは Arch Linux システムで Ruby on Rails フレームワークをセットアップする方法を説明します。
目次
インストール
Ruby on Rails を使うには Ruby をインストールする必要があるので、先に Ruby の記事を読んでインストールを済まして下さい。また、(UglifyJS JavaScript コンプレッサーの Ruby ラッパーである) uglifier のために nodejs パッケージも必要になります。
Ruby on Rails 自体は複数の方法でインストールできます:
選択肢 A: RubyGems
現在のユーザーで Rails をインストールするコマンド:
$ gem install rails
ドキュメントのビルドには時間がかかります。ドキュメントは不要の場合、--no-document
を install コマンドに付けて下さい。
$ gem install rails --no-document
gem は Ruby モジュールのパッケージマネージャであり、Arch Linux における pacman のようなものです。gem をアップデートするには、次を実行:
$ gem update
選択肢 B: pacgem
AUR の pacgemAUR を使って Rails をインストールすることができます。Pacgem は自動的に PKGBUILD を作成して、それぞれの gem の Arch パッケージを作成します。そしてパッケージは pacman を使ってインストールされます。
# pacgem rails
gem パッケージは次のコマンドでアップデートできます:
# pacgem -u
選択肢 C: AUR
AUR には ruby-railsAUR パッケージが存在します。
選択肢 D: Quarry バイナリリポジトリ
非公式の quarry リポジトリから ruby-rails をインストールしてください。
設定
Rails には WeBrick という名前のベーシックな HTTP サーバーが付属しています。テストアプリケーションを作成してテストすることができます。まず、rails コマンドでアプリケーションを作成:
$ rails new testapp_name
現在の作業ディレクトリの中に新しいフォルダが作成されます。
$ cd testapp_name
次にウェブサーバーを起動します。デフォルトではポート 3000 を使います:
$ rails server
ローカルマシンのブラウザから http://localhost:3000 を開いて testapp_name のウェブサイトを開いてください。
テストページには "Welcome aboard" と表示されるはずです。
アプリケーションサーバー
Ruby On Rails に内蔵されている HTTP サーバー (WeBrick) は開発用には便利ですが、本番環境での使用は推奨されません。#Thin, #Unicorn, Phusion Passenger などのアプリケーションサーバーを使って下さい。
Thin
Thin は高速でシンプルな Ruby ウェブサーバーです。
thin の gem をまずインストールしてください:
$ gem install thin
そして次のコマンドで起動:
$ thin start
Unicorn
Unicorn はスタンドアロンのアプリケーションサーバーで、クライアントと直接対話することはできません。その代わりに、ウェブサーバーがクライアントと Unicorn の間に入って、必要に応じてリクエストを送ります。Unicorn は基本的に Mongrel が元になっています。Unicorn は Github に使われており、リクエストを処理するのに一番適した子プロセスを出来る限り使うようなアーキテクチャになっています。Unicorn と Mongrel の違いについては こちら に説明があります。
Unicorn の gem をインストール:
# gem install unicorn
アプリケーションの設定ファイルを /etc/unicorn/
に作成。以下は Redmine の設定例です ([1] を参照):
/etc/unicorn/redmine.ru
working_directory "/srv/http/redmine" pid "/tmp/redmine.pid" preload_app true timeout 60 worker_processes 4 listen 4000 stderr_path('/var/log/unicorn.log') GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true after_fork do |server, worker| #start the worker on port 4000, 4001, 4002 etc... addr = "0.0.0.0:#{4000 + worker.nr}" # infinite tries to start the worker server.listen(addr, :tries => -1, :delay => -1, :backlog => 128) #Drop privileges if running as root worker.user('nobody', 'nobody') if Process.euid == 0 end
次のコマンドで起動:
# /usr/bin/unicorn -D -E production -c /etc/unicorn/redmine.ru
Systemd サービス
/etc/systemd/system/unicorn.service
に以下を記述:
/etc/systemd/system/unicorn.service
[Unit] Description=Unicorn application server After=network.target [Service] Type=forking User=redmine ExecStart=/usr/bin/unicorn -D -E production -c /etc/unicorn/redmine.ru [Install] WantedBy=multi-user.target
これで systemctl を使って簡単に unicorn を起動・停止できます。
Nginx の設定
Nginx をセットアップしてから、以下のように unicorn を上流サーバーとして設定してください (警告: 以下は省略した例です。おそらく設定を追加しないと機能しません):
http { upstream unicorn { server 127.0.0.1:4000 fail_timeout=0; server 127.0.0.1:4001 fail_timeout=0; server 127.0.0.1:4002 fail_timeout=0; server 127.0.0.1:4003 fail_timeout=0; } server { listen 80 default; server_name YOURHOSTNAMEHERE; location / { root /srv/http/redmine/public; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://unicorn; } } }
Apache/Nginx (Phusion Passenger を使用)
Passenger (別名 mod_rails
) は Nginx や Apache で利用できるモジュールで、Rails サーバー環境のセットアップをはるかに簡単にします。Nginx は Apache のようにモジュールをサポートしていないので、Passenger を使うには mod_rails
でコンパイルする必要があります。Passenger が勝手にコンパイルをおこなってくれます。Apache の場合、Passenger がモジュールの設定をしてくれます。
まずは 'passenger' の gem をインストール:
# gem install passenger
Apache を使用する場合、以下を実行:
# passenger-install-apache2-module
http://example.com/yourapplication のように、sub-URI で rails アプリケーションをデプロイする場合、追加設定が必要になります。modrails のドキュメント を見て下さい。
Nginx の場合:
# passenger-install-nginx-module
インストーラはインストールに関する追加情報を出力します (インストールする追加ライブラリなど)。
Nginx でアプリケーションを表示するには、以下のように設定:
server { server_name app.example.org; root path_to_app/public; # Be sure to point to 'public' folder! passenger_enabled on; rails_env development; # Rails environment. }
Puma (Nginx をリバースプロキシサーバーとして使用)
Puma (Github ページ) は Ruby/Rack アプリケーションのためのシンプル・高速・並列動作の HTTP 1.1 サーバーで、Webrick や Mongrel を置き換えることを目指しています。Rubinius の go-to サーバーとして設計されているだけでなく、JRuby や MRI とも上手く動作します。リバースプロキシサーバーはロードバランサとして機能し、外部リクエストをウェブアプリのプールに振り分けます。
ウェブサーバーはサーバー用のユーザーとグループで使うのが良いので、ユーザーとグループ#ユーザーを追加する例を見て下さい。以下ではユーザー名として rails
を、グループ名として server
を、rails のアプリ名として my_app
を使います。
まずは /var/www/my_app
にあなたのアプリをコピーしてください。そして以下のコマンドで所有者を設定します:
# cd /var/www/ # chown -R rails:server my_app
そして、次のコマンドでパーミッションを設定:
# chmod -R 775 my_app
次に Gemfile に puma gem
を追加してインストール:
$ cd my_app $ bundle install
また、pacman で nginx
をインストールしてください。
アプリフォルダに以下のコマンドで sockets, pids, log フォルダを作成:
$ mkdir -p shared/pids shared/sockets shared/log
nginx.conf
をバックアップ:
# cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
お好きなエディタで nginx.conf ファイルを新しく作成して以下のコードをコピー、自由に編集してください:
#user html; worker_processes 1; # this may connect with the worker numbers puma can use. #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { upstream app { # Path to Puma SOCK file, as defined previously server unix:/var/www/my_app/shared/sockets/puma.sock; } server { listen 80; server_name localhost; # or your server name root /var/www/my_app/public; try_files $uri/index.html $uri @app; location @app { proxy_pass http://app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } error_page 500 502 503 504 /500.html; client_max_body_size 4G; keepalive_timeout 10; } }
nginx
サービスを起動してください。
puma サーバーを起動する方法は複数存在します。以下では2つの方法を推奨しています:
どちらの方法にしても、config/puma.rb
ファイルを作成して以下のコードをコピーしてください。そして必要に応じて修正を加えます:
# Change to match your CPU core count # You can check available worker numbers with $ grep -c processor /proc/cpuinfo # also see the comment in the nginx.conf workers 2 # Min and Max threads per worker #threads 1, 6 app_dir = File.expand_path("../..", __FILE__) shared_dir = "#{app_dir}/shared" # Default to production #rails_env = ENV['RAILS_ENV'] || "production" #environment rails_env # Set up socket location bind "unix://#{shared_dir}/sockets/puma.sock" # Logging #stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true # Set master PID and state locations pidfile "#{shared_dir}/pids/puma.pid" #state_path "#{shared_dir}/pids/puma.state" #activate_control_app #on_worker_boot do # require "active_record" # ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished # ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env]) #end
選択肢 A: 設定ファイルを使う
次のコマンドでサーバーを起動:
$ bundle exec puma -C config/puma.rb
-d
パラメータを使うことでバックグラウンドで起動することもできます。kill
したくなったら以下で確認してください:
$ pgrep puma
ログアウトしても実行し続けるには、以下を使います:
$ nohup bundle exec puma -C config/puma.rb &
ただしシステムを再起動すると、プロセスは消失します。
選択肢 B: systemd を使う
~/.config/systemd/user/
に新しい systemd ユニット puma.service
を作成して以下のコードをコピーしてください (gem をグローバルにインストールした場合、ExecStart のパスは /usr/local/bin/ に変更できます):
[Unit] Description=Puma application server After=network.target [Service] WorkingDirectory=/var/www/my_app #Environment=RAILS_ENV=production PIDFile=/var/www/my_app/shared/pids/puma.pid ExecStart=/home/rails/.gem/ruby/2.2.0/bin/bundle exec \ /home/rails/.gem/ruby/2.2.0/bin/puma \ -C /var/www/my_app/config/puma.rb [Install] WantedBy=default.target
次のコマンドで puma を起動:
$ systemctl --user start puma
puma をシステム全体で有効化するには、/etc/systemd/system/
に puma.service
を保存して、以下のように修正してください:
[Unit] Description=Puma application server After=network.target [Service] WorkingDirectory=/var/www/my_app #Environment=RAILS_ENV=production User=rails PIDFile=/var/www/my_app/shared/pids/puma.pid ExecStart=/home/rails/.gem/ruby/2.2.0/bin/bundle exec \ /home/rails/.gem/ruby/2.2.0/bin/puma \ -C /var/www/my_app/config/puma.rb [Install] WantedBy=multi-user.target
詳しくは #参照 を見て下さい。また、capistrano を使えばプロダクションモードで簡単にアプリをデプロイすることができます。
データベース
ほとんどの Web アプリケーションは、ある種のデータベースと対話する必要があります。 ActiveRecord(Rails がデータベース抽象化を提供するために使用する ORM )は、MySQL、SQLite、および PostgreSQL で最も人気のあるいくつかのデータベースベンダーをサポートしています。次に、データベースに接続できる Rails アプリケーション Web サイトのファイル config /database.yml を構成する必要があります。
SQLite
SQLite は Ruby on Rails のデフォルトの軽量データーベースです。SQLite を使用するには、sqlite をインストールしてください。
PostgreSQL
postgresql をインストールします。
Rails 用にインストールします。
# gem install pg
または、プロジェクトの Gemfile に gem を追加し、bundle を使用します。
新しい Rails の Web サイトを作成します。
# rails new my_web_site -d postgresql
MySQL
まず、MySQL サーバーをインストールし、設定します。この方法については MariaDB を参照してください。
ネイティブの拡張機能を持つ gem が必要です。root でインストールするのがベストでしょう。
# gem install mysql
パラメータ -d
を使用することで、MySQL 用に設定された rails アプリケーションを生成することができます。
$ rails new testapp_name -d mysql
データベースアクセス設定
どのデータベース (MySQL, Postgresql, SQlite (デフォルト)) を使用する場合でも、config/database.yml
を編集する必要があります。Rails は、開発環境、テスト環境、本番環境、その他の環境で異なるデータベースを使用します。以下は、localhost で動作する MySQL の開発用設定例です。
default: adapter: mysql (or postgresql or sqlite) username: my_user_name_access password: my_secret_password
安全上の理由から、パスワードを直接テキストファイルに平文で書き込まないのがよい方法です。 その代わりに、"my_secret_password" を "'<%= ENV["MYSQL_PASSWD"] %>'" で置き換えることができます。ここで MYSQL_PASSWD は、サーバーが使用するユーザー環境 (~/.profile または ~/.bashrc または ~/.zshrc) からエクスポートした環境変数で、あなたの選択と ユーティリティによって決定される。<%= ENV....で囲んでください。パスワードに # や ! などの特殊文字が含まれている場合は、"'" で囲んで検索してください。
Rails からデータベースを作成する
なお、実際に MySQL や Postgresql、Sqlite を使ってデータベースを作成する必要はなく、Rails から直接行うことができます。
rails-4.Xバージョンの場合。
# rake db:create
rails-5.Xバージョンの場合。
# rails db:create (Rails-5.X バージョンの場合)
エラーが表示されなければ、データベースが作成され、Rails が MySQL データベースと対話できるようになっています。
Rails パーフェクトセットアップ
複数のバージョンの Ruby で動作する Phusion Passenger。
- Arch Linux: シンプル、軽量なディストリビューション。 ;)
- Nginx: 高い並行性・性能、低いメモリ使用量に注力している高速かつ軽量なウェブサーバー。
- Passenger (別名 mod_rails または mod_rack): Apache と Nginx の両方のウェブサーバーに対応。Ruby on Rails ウェブフレームワークで作られたアプリケーションなど、Ruby ウェブアプリケーションをデプロイします。
- Ruby Version Manager (RVM): インタプリタから gem セットまで複数の Ruby 環境を簡単にインストール・管理・作業することができるコマンドラインツール。RVM は完全に自己完結した専用環境でプロジェクトをデプロイします。特定バージョンの Ruby から、アプリケーションを実行するのに必要な gem の正確なセットまで。
- SQLite: Ruby on Rails のデフォルト、軽量なデータベース。
ステップ 0: SQLite
sqlite をインストールします。
ステップ 1: RVM
こちらに書かれているように RVM をマルチユーザーインストールしてください。
'ユーザーを rvm グループに追加'のステップでは、以下を実行:
# usermod -a -G rvm http # usermod -a -G rvm nobody
http
と nobody
はそれぞれ Nginx と Passenger に関連するユーザーです。
ステップ 2: Ruby
RVM をインストールできたら、最新の Ruby インタプリタをインストールします:
$ rvm install 2.0.0
ステップ 3: Nginx と Passenger
以下を実行して passenger で nginx をインストール:
$ rvm use 2.0.0 $ gem install passenger $ rvmsudo passenger-install-nginx-module
passenger gem が default gemset に追加されます。
Nginx のソースがダウンロードされて、コンパイル・インストールされます。Nginx のデフォルトインストール先は /opt/nginx
になります。
完了したら /opt/nginx/conf/nginx.conf
に以下のように http ブロックを追加してください:
http { ... passenger_root /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-3.0.9; passenger_ruby /usr/local/rvm/wrappers/ruby-2.0.0-p353/ruby; ... }
ステップ 4: Gemsets と Apps
Rails アプリケーションごとに、gemset を用意する必要があります。例えば、RefineryCMS と BrowserCMS という Rails ベースの2つのオープンソースコンテンツマネジメントシステムを試してみようとします。
まず RefineryCMS をインストール:
$ rvm use 2.0.0@refinery --create $ gem install rails -v 4.0.1 $ gem install passenger $ gem install refinerycms refinerycms-i18n sqlite3
refineria という名前で RefineryCMS インスタンスをデプロイ:
$ cd /srv/http/ $ rvmsudo refinerycms refineria
別の gemset に BrowserCMS をインストール:
$ rvm use 2.0.0@browser --create $ gem install rails -v 4.0.1 $ gem install passenger $ gem install browsercms sqlite3
navegador という名前で BrowserCMS インスタンスをデプロイ:
$ cd /srv/http/ $ rvmsudo browsercms demo navegador $ cd /srv/http/navegador $ rvmsudo rake db:install
Passenger for Nginx と Passenger Standalone
Passenger アイテムが3回、異なる意図でインストールされたことをご覧ください。
- 2.0.0 => for Nginx,
- 2.0.0@refinery => Standalone
- 2.0.0@browser => Standalone
Passenger for Nginx と Passenger Standalone を組み合わせる作戦です。まず、最もよく使う Ruby 環境(インタープリタと gemset)を特定する必要があります。この設定では、Ruby インタープリタとデフォルトの gemset が選択されています。その環境を利用するために、Passenger for Nginx の設定を行います(ステップ3)
- 選択した環境内のアプリケーションは、本記事の Apache/Nginx (Phusion Passenger を使用)) と同様に提供することが可能です。
- 異なる Ruby バージョンや gemset を使用するアプリケーションは、Passenger Standalone を通して個別に提供し、リバースプロキシ設定(ステップ6)によりメインの Web サーバーに接続することができます。
ステップ 5: .rvmrc ファイルと所有者
このステップは、セットアップの正しい動作のために非常に重要です。RVM はフォルダーを変更する際に .rvmrc ファイルを探し、見つかれば読み込みます。このファイルには通常、次のような行を記述します。
rvm <ruby_version>@<gemset_name> です。
アプリケーションのルートフォルダの入り口に、指定された環境が設定されるようになります。
/srv/http/refineria/.rvmrc
を作成:
# echo "rvm ree@refinery" > /srv/http/refineria/.rvmrc
/srv/http/navegador/.rvmrc
を作成:
# echo "rvm 2.0.0@browser" > /srv/http/navegador/.rvmrc
RVM が .rvmrc を見つけるたびに、与えられたファイルを信頼するかどうか尋ねられるので、今作成した2つのファイルを確認する必要があります。
これらのファイルは、関係するプログラムが正しい gems を見つけることを支援します。
また、アプリケーションのファイルやフォルダの所有者が正しいユーザーでない場合、データベースの書き込みアクセスの問題に直面することになります。rvmsudo を使うと、Rails で生成されたアーカイブは root 所有になります。一方、nobody は Passenger のユーザで、変更していない場合、誰が使うのか、所有する必要があるのかを、修正する必要があります。
# chown -R nobody.nobody /srv/http/refineria /srv/http/navegador
ステップ 6: リバースプロキシ
アプリケーションの Passenger Standalone ウェブサーバーを起動してください:
$ cd /srv/http/refineria $ rvmsudo passenger start --socket tmp/sockets/passenger.socket -d
そして以下を実行:
$ cd /srv/http/navegador $ rvmsudo passenger start --socket tmp/sockets/passenger.socket -d
Passenger Standalone を始めて実行したときにインストールが実行されます。
一般的な TCP ソケットの代わりに unix ドメイン ソケットが使われます。unix ドメインは TCP ソケットよりも高速に動作します。
システムの起動時に Passenger Standalone デーモンを起動
Do you have a script? Please post it here.
The systemd script below was made for a Typo blog I host at /srv/http/typo. It's located at /etc/systemd/system/passenger_typo.service. I set the Environment= tags (see "man systemd.exec") from the output of "rvm env". The only exception was PATH=, which I had to combine from my regular PATH and the output of rvm env.
Note: If you don't set the "WorkingDirectory=" variable to your application folder, passenger will fail to find your app and will subsequently shut itself down.
[Unit] Description=Passenger Standalone Script for Typo After=network.target [Service] Type=forking WorkingDirectory=/srv/http/typo PIDFile=/srv/http/typo/tmp/pids/passenger.pid Environment=PATH=/usr/local/rvm/gems/ruby-2.0.0-p0@typo/bin:/usr/local/rvm/gems/ruby-2.0.0-p0@global/bin:/usr/local/rvm/rubies/ruby-2.0.0-p0/bin:/usr/local/rvm/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/bin/core_perl Environment=rvm_env_string=ruby-2.0.0-p0@typo Environment=rvm_path=/usr/local/rvm Environment=rvm_ruby_string=ruby-2.0.0-p0 Environment=rvm_gemset_name=typo Environment=RUBY_VERSION=ruby-2.0.0-p0 Environment=GEM_HOME=/usr/local/rvm/gems/ruby-2.0.0-p0@typo Environment=GEM_PATH=/usr/local/rvm/gems/ruby-2.0.0-p0@typo:/usr/local/rvm/gems/ruby-2.0.0-p0@global Environment=MY_RUBY_HOME=/usr/local/rvm/rubies/ruby-2.0.0-p0 Environment=IRBRC=/usr/local/rvm/rubies/ruby-2.0.0-p0/.irbrc ExecStart=/bin/bash -c "rvmsudo passenger start --socket /srv/http/typo/tmp/sockets/passenger.socket -d" [Install] WantedBy=multi-user.target
ステップ 7: デプロイメント
サブドメインを使用
/opt/nginx/conf/nginx.conf
を編集して以下のように設定:
## RefineryCMS ## server { server_name refinery.domain.com; root /srv/http/refineria/public; location / { proxy_pass http://unix:/srv/http/refineria/tmp/sockets/passenger.socket; proxy_set_header Host $host; } } ## BrowserCMS ## server { server_name browser.domain.com; root /srv/http/navegador/public; location / { proxy_pass http://unix:/srv/http/navegador/tmp/sockets/passenger.socket; proxy_set_header Host $host; } }
サブドメインを使用しない
何らかの理由でアプリケーションでサブドメインを使わずに site.com/railsapp
というような url を使いたい場合、以下のように設定することができます:
server { server_name site.com; #Base for the html files etc root /srv/http/; #First application you want hosted under domain site.com/railsapp location /railsapp { root /srv/http/railsapp/public; #you may need to change passenger_base_uri to be the uri you want to point at, ie: #passenger_base_uri /railsapp; #but probably only if you're using the other solution with passenger phusion proxy_pass http://unix:/srv/http/railsapp/tmp/sockets/passenger.socket; proxy_set_header Host $host; } #Second applicatino you want hosted under domain site.com/anotherapp location /anotherapp { root /srv/http/anotherapp/public; #same thing about the passenger_base_uri here, but with value /anotherapp instead proxy_pass http://unix:/srv/http/anotherapp/tmp/sockets/passenger.socket; proxy_set_header Host $host; } }
nginx
サービスを起動すれば site.com/railsapp と site.com/anotherapp から CMS にアクセスできます。
参照
- http://beginrescueend.com/integration/passenger
- http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions
- http://www.ruby-journal.com/how-to-setup-rails-app-with-puma-and-nginx/
- https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-puma-and-nginx-on-ubuntu-14-04
参照
- Ruby on Rails http://rubyonrails.org/download
- Mongrel http://mongrel.rubyforge.org