-
Notifications
You must be signed in to change notification settings - Fork 9
rails4 getting started
Ruby on Railsは、Rubyで書かれたポピュラーなフレームワークです。Rails 4.0のベータ版が、2013年1月25日にリリースされました。以前のバージョンのRailsをHeroku上でお使いになる場合は、Getting Started with Rails 3.x on Herokuを参照して下さい。
この記事は、Rails 4を使い始めるに辺り、深く掘り下げた記事となります。既に、HerokuとRailsに慣れ親しんでいる場合は、シンプルなRails 4のHerokuガイドを参照して下さい。
Rails 4をHeroku上で動作させるには、以下のものが必要となります。:
- 基本的なRuby/Railsの知識。Ruby 1.9.3以降、Rubygems、Bundler、Rails 4がインストール済みであること。
- 基本的なGitの知識
- Herokuのユーザーアカウント。サインアップは、フリー、かつ簡単に行えます。
まずは、ローカル端末にHeroku Toolbeltをインストールして下さい。インストールすることで、HerokuのCLI、Foreman、Gitのリビジョン管理システムへのアクセスが可能となります。また、RubyとRailsがインストールされている必要があります。
一度、インストールをしてしまえば、シェルからheroku
コマンドを実行出来るようになります。Herokuのアカウント作成時に使用したemailアドレスとパスワードを使い、以下のようにログインして下さい。:
:::term
$ heroku login
Enter your Heroku credentials.
Email: [email protected]
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub
既存のssh
キーをアップロードするか、新たにssh
キーを作成しますので、エンターを押下して下さい。ssh
キーは、この先、コードをHerokuにプッシュする際に使用されます。
既存のアプリから作業を始めることもあるでしょう。その場合、まずは、Rails 4へのアップグレードをお願いします。そうでない場合、一般的なRails 4のアプリがサンプルとしては最適でしょう。以下のように作業を進めます。新規のアプリを作成する前に、$ rails -v
コマンドを実行し、開発時にRails 4.xを使用していることを確認して下さい。また、Railsの新バージョンを入手するには下記のコマンドを実行します。
:::term
$ gem install rails --version 4.0.0
その後で、新規アプリを作成してみましょう。:
:::term
$ rails new myapp --database=postgresql
$ cd myapp
Herokuの統合環境は、以前、Railsのプラグインを使用することに依存していましたが、Rails 4では、それらの依存関係を削除しました。静的なアセットをHeroku上に提供することやログを取る機能を使用可能にするには、以下のgemをGemfile
へ追加して下さい。:
:::ruby
gem 'rails_12factor', group: :production
その後で、下記を実行して下さい。:
:::term
$ bundle install
ここまでが、Herokuと統合する際の必要最小限の作業となります。
アプリ作成時、--database=postgresql
のパラメータを指定し、postgresql
の使用を明示していないのであれば、pg
というgemをRailsプロジェクトに追加する必要があります。Gemfile
内の該当箇所を下記のように変更して下さい。:
:::ruby
gem 'sqlite3'
上記箇所をこちらに変更します。:
:::ruby
gem 'pg'
依存しているgemの再インストールをして下さい。(新規のGemfile.lock
を生成するためです。):
:::term
$ bundle install
なぜこの変更が必要か、また、postgresをローカル環境で実行させるアプリの設定方法に関しては、より多くの情報を得ることが可能です。こちらを参照して下さい。HerokuでSqlite3が使用出来ない理由
Rails 4では、Ruby 1.9.3、またはそれ以降のRubyを必要とします。Herokuは、直近のバージョンのRubyをインストールしますが、Gemfile
に以下のように追記することで、バージョンを明示することも可能です。:
:::ruby
ruby "1.9.3"
または、
:::ruby
ruby "2.0.0"
ローカルでも、同一のバージョンのRubyを使うべきです。$ ruby -v
コマンドを実行することで、どのバージョンを使っているかを確認することが出来ます。より詳細な情報はこちらHerokuで使用するRubyのバージョンを明示するを参照して下さい。
Herokuは、プロジェクトのデプロイをする際、gitのシステムに依存しています。gitとは、分散型バージョン管理システムのことです。プロジェクトが未だgitに保存されていない場合、まずは、システム内にgit
がインストールされているかを確認して下さい。
:::term
$ git --help
usage: git [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[-c name=value] [--help]
<command> [<args>]
# ...
上記のコマンドを実行しても、アウトプットが得られない場合や、command not found
のエラーが返ってきた場合、gitをシステム内にインストールする必要があります。Heroku toolbeltがインストールされていることを確認して下さい。
gitが機能していることが分かれば、次にRailsアプリのディレクトリに移動して下さい。その後で、Railsアプリのディレクトリで、下記の3つのコマンドを実行して下さい。このコマンドは、gitの初期化とコードをgitへコミットするためのものです。:
:::term
$ git init
$ git add .
$ git commit -m "init"
さて、あなたのアプリケーションがgitへコミットされました。これで、Herokuへのデプロイが可能となります。
Railsアプリが格納されているディレクトリにいることを確認して下さい。その後で、Herokuへアプリをクリエイトします。:
:::term
$ heroku create
Creating calm-brook-1268... done, stack is cedar
http://calm-brook-1268.herokuapp.com/ | [email protected]:calm-brook-1268.git
Git remote heroku added
下記のコマンドを実行することで、プロジェクトがリモートに追加されたことを確認して下さい。
:::term
$ git config -e
fatal: not in a git directory
というエラーが出なければ、Herokuへのデプロイが安全に行える状態です。デプロイ後、データベースのマイグレートが必要となります。適切にスケールされていることを確認して下さい。また、今後発生し得る問題をデバグするには、ログを使用して下さい。
コードのデプロイ:
:::term
$ git push heroku master
Counting objects: 112, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (77/77), done.
Writing objects: 100% (112/112), 27.01 KiB, done.
Total 112 (delta 20), reused 112 (delta 20)
-----> Ruby/Rails app detected
-----> Using Ruby version: ruby-2.0.0
-----> Installing dependencies using Bundler version 1.3.0.pre.5
Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin --deployment
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/..
Fetching git://github.com/heroku/rails3_serve_static_assets.git
Fetching git://github.com/heroku/rails_log_stdout.git
Installing rake (10.0.3)
Installing i18n (0.6.2)
Installing minitest (4.6.1)
Installing multi_json (1.6.1)
Installing atomic (1.0.1)
Installing thread_safe (0.1.0)
Installing tzinfo (0.3.35)
Installing activesupport (4.0.0)
Installing builder (3.1.4)
Installing erubis (2.7.0)
Installing rack (1.5.2)
Installing rack-test (0.6.2)
Installing actionpack (4.0.0)
Installing mime-types (1.21)
Installing polyglot (0.3.3)
Installing treetop (1.4.12)
Installing mail (2.5.3)
Installing actionmailer (4.0.0)
Installing activemodel (4.0.0)
Installing activerecord-deprecated_finders (0.0.3)
Installing arel (4.0.0)
Installing activerecord (4.0.0)
Installing coffee-script-source (1.5.0)
Installing execjs (1.4.0)
Installing coffee-script (2.2.0)
Using json (1.7.7)
Installing rdoc (3.12.2)
Installing thor (0.17.0)
Installing railties (4.0.0)
Installing coffee-rails (4.0.0)
Installing hike (1.2.1)
Installing jbuilder (1.0.2)
Installing jquery-rails (2.2.1)
Installing pg (0.14.1)
Using bundler (1.3.0)
Installing tilt (1.3.3)
Installing sprockets (2.9.0)
Installing sprockets-rails (2.0.0.rc3)
Installing rails (4.0.0)
Using rails3_serve_static_assets (0.0.1) from git://github.com/heroku/rails3_serve_static_assets.git (at master)
Using rails_log_stdout (0.0.1) from git://github.com/heroku/rails_log_stdout.git (at master)
Installing sass (3.2.6)
Installing sass-rails (4.0.0)
Installing turbolinks (1.0.0)
Installing uglifier (1.3.0)
Your bundle is complete! It was installed into ./vendor/bundle
Post-install message from rdoc:
Depending on your version of ruby, you may need to install ruby rdoc/ri data:
<= 1.8.6 : unsupported
= 1.8.7 : gem install rdoc-data; rdoc-data --install
= 1.9.1 : gem install rdoc-data; rdoc-data --install
>= 1.9.2 : nothing to do! Yay!
Cleaning up the bundler cache.
-----> Preparing app for Rails asset pipeline
Running: rake assets:precompile
I, [2013-02-25T15:15:26.999810 #1771] INFO -- : Writing /tmp/build_8twtg5uo0zrj/public/assets/rails-a48208150b2c0da4f80797a999919b58.png
I, [2013-02-25T15:15:29.993217 #1771] INFO -- : Writing /tmp/build_8twtg5uo0zrj/public/assets/application-e4bf17ac068b4157db532671a5294743.js
I, [2013-02-25T15:15:30.065780 #1771] INFO -- : Writing /tmp/build_8twtg5uo0zrj/public/assets/application-a543268ce31a2798b68675fbfcb1bcdc.css
Asset precompilation completed (6.24s)
-----> Rails plugin injection
-----> Discovering process types
Procfile declares types -> (none)
Default types for Ruby/Rails -> console, rake, web, worker
-----> Compiled slug size: 33.1MB
-----> Launching... done, v6
http://calm-brook-1268.herokuapp.com deployed to Heroku
To [email protected]:calm-brook-1268.git
* [new branch] master -> master
注意:Rails 4では、本番環境に静的インデックスのページを管理しなくなりました。新規のアプリを作成した場合、ルートとなるページは存在しないこととなるでしょう。
アプリケーションにデータベースをお使いでしたら、下記のコマンドを実行することで、手動でデータベースをマイグレートする必要があります。:
:::term
$ heroku run rake db:migrate
heroku run
の後に付加されたコマンドは全てHerokuのdyno上で実行されます。
Herokuへのコードのデプロイは完了しましたので、Herokuへプロセスタイプを実行するよう指示を送ることが出来ます。Herokuでは、dyno上で関連するコマンドを実行することにより、これを実現しています。dynoとは、Herokuの構成における基本単位のことで、軽量なコンテナとなります。
web
プロセスタイプとして、1dynoが実行中であることを確認してみましょう。:
:::term
$ heroku ps:scale web=1
アプリのdynoの状態を確認することが可能です。heroku ps
コマンドは、アプリケーションで実行されているdynoをリスト化します。:
:::term
$ heroku ps
=== web: `rails server -p $PORT -e $RAILS_ENV`
web.1: up for 5s
1dynoが実行されていることを確認しました。
heroku open
を実行することで、ブラウザ上でアプリを訪問することが可能です。
:::term
$ heroku open
Opening calm-brook-1268... done
開発中、Herokuはデフォルトでアプリ名を提供してくれます。アプリをスケールする準備が整い、本番環境でHerokuを使用する際、カスタムドメインを名称として追加することが可能です。
アプリが正常に動作するよう開発を行っている際、何かしらの問題に遭遇したなら、まずは、ログを確認する必要があります。
Herokuでは、時系列のイベントのストリームとしてログを扱います。ログは、アプリケーションのコンポーネントを実行する全dynoから収集されます。HerokuのLogplexは、これらの全イベントへのチャンネルとなります。
稼働中のアプリの情報を参照するには、heroku logs
というログ用コマンドを実行することで可能となります。:
:::term
$ heroku logs
2013-02-26T01:47:32+00:00 heroku[web.1]: State changed from created to starting
2013-02-26T01:47:33+00:00 heroku[web.1]: Starting process with command `rails server -p 16142 -e $RAILS_ENV`
2013-02-26T01:47:35+00:00 app[web.1]: [2013-02-26 01:47:35] INFO WEBrick 1.3.1
2013-02-26T01:47:35+00:00 app[web.1]: [2013-02-26 01:47:35] INFO WEBrick::HTTPServer#start: pid=2 port=16142
2013-02-26T01:47:35+00:00 app[web.1]: [2013-02-26 01:47:35] INFO ruby 2.0.0 (2013-02-24) [x86_64-linux]
2013-02-26T01:47:36+00:00 heroku[web.1]: State changed from starting to up
以下のように--tail
フラグをコマンドに付加することで、全ストリームのログを取得することが可能です。:
:::term
$ heroku logs --tail
web dynoを1つだけ使用しているアプリでは、1時間アイドル状態が続いた場合、dynoがスリープ状態となります。このことは、スリープ状態となってから最初のリクエストを受け付けた際に、アプリの起動が遅くなる原因となります。継続的にリクエストが発生する場合は、遅延なく通常通り動作します。
これを避けるために、下記の例のように、web dynoを1つ以上にスケールすることが可能です。:
:::term
$ heroku ps:scale web=2
Herokuは、アプリ毎に750時間フリーのdynoを提供しています。2つのdynoでアプリを実行している場合は、この制限を越えてしまうでしょう。そのため、以下のようにスケールを元に戻しましょう。:
:::term
$ heroku ps:scale web=1
Herokuは、heroku run
コマンドを使用することで、one-off dynoの仕組み内において、コマンドの実行を許可しています。one-off dynoとは、必要な時にのみ実行されるスクリプトとアプリケーションのことです。このone-off dynoをRailsのコンソールプロセスを起動させるのに使ってみて下さい。実際のアプリの環境で試験することが可能です。:
:::term
$ heroku run rails console
Running `rails console` attached to terminal... up, run.2591
Loading production environment (Rails 4.0.0)
irb(main):001:0>
Rakeはコンソールと同様に付加プロセスとして実行することが出来ます。:
:::term
$ heroku run rake db:migrate
デフォルトで、rails server
コマンドで使用されるWebサーバーは、Webrickとなります。これはテスト環境では良いかもしれません。ですが、本番環境ではもっと堅牢なWebサーバーへ切り替えたくなるかもしれません。Cedar上では、UnicornをWebサーバーとして使用することを推奨します。あなたが選択するWebサーバーがどれであれ、本番環境のアプリでは、常にProcfile
へ、はっきりと使用するWebサーバーを明示するべきです。
まず最初に、アプリのGemfile
へUnicornを追加して下さい。:
gem 'unicorn'
$ bundle install
を実行して下さい。実行することで、Unicornを使用するよう、アプリを設定する準備が整います。
config/unicorn.rb
にUnicorn用の設定ファイルを作成して下さい。:
$ touch config/unicorn.rb
現在、HerokuではUnicornに関する詳細な設定オプションを追加中です。詳細は、HerokuのUnicornに関するドキュメントに記載しています。:
# config/unicorn.rb
worker_processes 3
timeout 30
preload_app true
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
このデフォルト設定は、Active Recordを使用するスタンダードなRailsアプリで使われることを前提としています。オフィシャルのUnicornに関するドキュメントにある異なるオプションに関しても、精通しておくべきでしょう。
最後に、アプリケーションのルートディレクトリ上にProcfile
を作成することで、あなたのRailsアプリがどのように動作するかをHerokuへ伝える必要があります。
Procfileというファイルを作成することで、webプロセスを起動するのに使用されるコマンドを下記のように変更して下さい。:
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
注意: Procfile
という名称は繊細です。名称の1文字目は必ず大文字にして下さい。
Foremanを使って、Procfileをローカル環境でテストしてみましょう。:
:::term
$ foreman start
18:24:56 web.1 | I, [2013-03-13T18:24:56.885046 #18793] INFO -- : listening on addr=0.0.0.0:5000 fd=7
18:24:56 web.1 | I, [2013-03-13T18:24:56.885140 #18793] INFO -- : worker=0 spawning...
18:24:56 web.1 | I, [2013-03-13T18:24:56.885680 #18793] INFO -- : master process ready
18:24:56 web.1 | I, [2013-03-13T18:24:56.886145 #18795] INFO -- : worker=0 spawned pid=18795
18:24:56 web.1 | I, [2013-03-13T18:24:56.886272 #18795] INFO -- : Refreshing Gem list
18:24:57 web.1 | I, [2013-03-13T18:24:57.647574 #18795] INFO -- : worker=0 ready
問題が無さそうです。Ctrl-Cを押し、Foremanを終了させて下さい。変更箇所をHerokuへデプロイして下さい。:
:::term
$ git add .
$ git commit -m "use unicorn via procfile"
$ git push heroku
ps
コマンドを打ってみて下さい。webプロセスがUnicornをwebサーバーとして使用していることを確認することが出来ます。
:::term
$ heroku ps
Process State Command
------------ ------------------ ------------------------------
web.1 starting for 3s unicorn -p $..
Unicornを使用していることは、ログにも反映されます。:
:::term
$ heroku logs
2013-03-14T01:57:55+00:00 heroku[web.1]: State changed from up to starting
2013-03-14T01:57:59+00:00 heroku[web.1]: Starting process with command `unicorn -p 26253 -E $RACK_ENV`
2013-03-14T01:58:00+00:00 app[web.1]: => Rails 4.0.0 application starting in production on http://0.0.0.0:27993
2013-03-14T01:58:00+00:00 app[web.1]: I, [2013-03-14T01:58:00.253906 #2] INFO -- : listening on addr=0.0.0.0:26253 fd=7
2013-03-14T01:58:00+00:00 app[web.1]: I, [2013-03-14T01:58:00.254256 #2] INFO -- : worker=0 spawning...
2013-03-14T01:58:00+00:00 app[web.1]: I, [2013-03-14T01:58:00.257455 #2] INFO -- : master process ready
2013-03-14T01:58:00+00:00 app[web.1]: I, [2013-03-14T01:58:00.258541 #4] INFO -- : Refreshing Gem list
2013-03-14T01:58:00+00:00 app[web.1]: I, [2013-03-14T01:58:00.258293 #4] INFO -- : worker=0 spawned pid=4
2013-03-14T01:58:01+00:00 app[web.1]: I, [2013-03-14T01:58:01.347337 #4] INFO -- : worker=0 ready
2013-03-14T01:58:01+00:00 heroku[web.1]: State changed from starting to up
Herokuへディプロイする際、Railsのアセットパイプラインの呼び出しには、いくつかのオプションがあります。詳細は、Rails 3.1+ Asset Pipeline on Heroku Cedarを参照して下さい。
Rails 4ではconfig.assets.initialize_on_precompile
オプションはリムーブされ、必要無くなりました。また、アセットのコンパイル時のエラーは、プッシュ時のエラーの原因ともなります。
アプリをプッシュ時に、クラッシュ(heroku ps
コマンドがcrashed
というステートを返します)した場合は、何が問題であったかをログで確認して下さい。一般的な問題をいくつかご紹介します。
ディプロイ時にgemが見つからない状態となっているのであれば、Bundlerのグループを確認してみて下さい。Herokuでは、開発環境やテスト環境のグループを無視して、アプリを構築します。あなたのアプリが、これらのグループのgemに依存しているのであれば、そのgemをこれらのグループの外に記述してみて下さい。
Rakefile
内のRSpecタスクを使った一般的な例を挙げてみます。Herokuへのディプロイ時に下記のエラーを見ることがあるなら:
:::term
$ heroku run rake -T
Running `bundle exec rake -T` attached to terminal... up, ps.3
rake aborted!
no such file to load -- rspec/core/rake_task
次にこの問題にも遭遇するでしょう。最初に、以下のようにローカルでも同様の現象を発生させて下さい。:
:::term
$ bundle install --without development:test
…
$ bundle exec rake -T
rake aborted!
no such file to load -- rspec/core/rake_task
gemロード時に、これらのRakeタスクを条件付きにすることで、この問題をフィックス出来ます。例えば以下のような感じです。:
:::ruby
begin
require "rspec/core/rake_task"
desc "Run all examples"
RSpec::Core::RakeTask.new(:spec) do |t|
t.rspec_opts = %w[--color]
t.pattern = 'spec/*_spec.rb'
end
rescue LoadError
end
ローカルで動作することを確認した上で、Herokuへプッシュして下さい。