Skip to content
hirotaka edited this page May 25, 2012 · 3 revisions

このクイックスタートでは、CedarスタックでRubySinatraを動かします。Railsアプリケーションは、Rails 3クイックスタートを参照してください。

事前準備

  • Ruby 1.9.2のバージョンがインストールされ、RubygemsとBundlerを含む基本的なRubyの知識。
  • 基本的なGitの知識
  • アプリケーションは、Ruby(MRI)1.9.2で動作する必要があります。
  • アプリケーションは、Bundlerを使用する必要があります。

ローカルワークステーションのセットアップ

ローカルワークステーションにHeroku Toolbeltをインストールします。これにより、Herokuコマンドラインクライアント、ForemanとGitのリビジョン管理システムへのアクセスを確保します。

インストールした後、コマンドシェルからherokuコマンドを使用します。Herokuのアカウントを作成した際に使用したメールアドレスとパスワードを使用してログインします。

:::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キーをアップロード、もしくは新しいキーを生成します。

アプリケーションを書く

既存のアプリがある場合はそちらを使用してください。もしなければ、ここに示した"Hello、World"というソースファイルをご使用ください。

web.rb

:::ruby
require 'sinatra'

get '/' do
  "Hello, world"
end

Bundler/Gemfileに依存関係を宣言する

CedarはGemfileの存在により、Rubyなどのアプリケーションを認識しています。あなたのアプリケーションでgemの依存関係を持っていない場合でも、規則に適ってRubyのアプリケーションと認識するように空のGemfileを作成する必要があります。

ローカルでのテストでは、分離された環境(bundle execやRVMで空のgemset)でアプリを実行するようにし、Gemfileにアプリが依存するすべてのgemがあるようにしてください。

上記で作成したSinatraアプリのGemfileは次のようになります。

Gemfile

:::ruby
source :rubygems
gem 'sinatra', '1.1.0'
gem 'thin'

ローカルでbundle installを実行します。

Foreman/Procfileにプロセスタイプを宣言する

Cedarはconfig.ruがあるアプリをRackアプリとして認識し、Webプロセスタイプを生成します。ただし、明示的にProcfileに独自のWebプロセスタイプを宣言することで、アプリケーションが実行される方法をより詳細に制御することができます。

ここで我々が取り組んでいるサンプルアプリケーションのProcfileは次のとおりです。

web: bundle exec ruby web.rb -p $PORT

直にRackアプリをデプロイする代わりに、独自のconfig.ruを実行することができるProcfileは次の通りです。

web: bundle exec rackup config.ru -p $PORT

これで、Procfileが準備できたので、Foremanを使用してアプリケーションを起動することができます。

:::term
$ foreman start

アプリケーションが5000番ポートで立ち上がります。curlまたはWebブラウザで動作をテストし、Ctrl-Cで終了します。

Gitでアプリケーションを保存する

これで、Gemfileに依存関係、Procfileにプロセスタイプ、web.rbにアプリケーションソースを記述することで、アプリケーションに必要な3つの主要な要素がそろいました。それでは、Gitに格納しましょう。

:::term
$ git init
$ git add .
$ git commit -m "init"

Heroku/Cedarにデプロイ

Cedarスタック上にアプリを作成します。

:::term
$ heroku create --stack cedar
Creating blazing-galaxy-997... done, stack is cedar
http://blazing-galaxy-997.herokuapp.com/ | [email protected]:blazing-galaxy-997.git
Git remote heroku added

コードをデプロイします。

:::term
$ git push heroku master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 660 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)

-----> Heroku receiving push
-----> Ruby app detected
-----> Installing dependencies using Bundler version 1.1
       Checking for unresolved dependencies.
       Unresolved dependencies detected.
       Running: bundle install --without development:test --path vendor/bundle --deployment
       Fetching source index for http://rubygems.org/
       Installing daemons (1.1.3)
       Installing eventmachine (0.12.10) with native extensions
       Installing rack (1.2.2)
       Installing tilt (1.3)
       Installing sinatra (1.1.0)
       Installing thin (1.2.7) with native extensions
       Using bundler (1.1)
       Your bundle is complete! It was installed into ./vendor/bundle
-----> Discovering process types
       Procfile declares types -> web
       Default types for Ruby  -> console, rake
-----> Compiled slug size is 6.3MB
-----> Launching... done, v4
       http://blazing-galaxy-997.herokuapp.com deployed to Heroku

To [email protected]:blazing-galaxy-997.git
 * [new branch]      master -> master

Web上でアプリを見る前に、アプリケーションのプロセスの状態をチェックしておきましょう。

:::term
$ heroku ps
Process       State               Command
------------  ------------------  ------------------------------
web.1         up for 10s          bundle exec ruby web.rb -p $PORT

Webプロセスは起動しています。詳細についてログを確認します。

:::term
$ heroku logs
2011-03-10T10:22:30-08:00 heroku[web.1]: State changed from created to starting
2011-03-10T10:22:32-08:00 heroku[web.1]: Running process with command: `bundle exec ruby web.rb -p 19037`
2011-03-10T10:22:33-08:00 app[web.1]: >> Thin web server (v1.2.7 codename No Hup)
2011-03-10T10:22:33-08:00 app[web.1]: >> Maximum connections set to 1024
2011-03-10T10:22:33-08:00 app[web.1]: >> Listening on 0.0.0.0:19037, CTRL+C to stop
2011-03-10T10:22:33-08:00 heroku[web.1]: State changed from starting to up

大丈夫そうです。これでheroku openでアプリケーションに接続することができます。

コンソール

Cedarは、アプリケーションの動作を試せるようにローカル端末に接続した対話的なRubyシェル(bundle exec irb)を立ち上げることができます。

:::term
$ heroku run console
Running `console` attached to terminal... up, ps.1
irb(main):001:0>

デフォルトでは、 irbにRuby標準ライブラリ以外はロードされません。ここからは、アプリケーションのファイルでいくつかをrequireすることもできます。または、コマンドラインでそれを行うこともできます。

:::term
$ heroku run console -r ./web

Rake

Rakeは、コンソールと同じように接続されたプロセスとして実行することができます。

:::term
$ heroku run rake db:migrate

SQLデータベースを使用する

デフォルトでは、非RailsアプリケーションはSQLデータベースが指定されていません。これはRedisやCouchDBのようなNoSQLデータベースを使用したり、あるいはデータベースを一切使用しない(上記のサンプル·アプリケーションの場合と同様)可能性があるためです。アプリケーションにSQLデータベースが必要な場合は次の操作を行います。

:::term
$ heroku addons:add shared-database

また、データベースを使用するために、アプリケーションにPostgresのgemを追加する必要があります。Gemfileに次のような行を追加します。

:::ruby
gem 'pg', '0.10.0'

ロギング

デフォルトでは、Rubyではstdoutにその出力をバッファリングします。Herokuのリアルタイムロギングを活用するには、Herokuのロギング基盤に直接ログメッセージを送信するよう、このバッファリングを無効にする必要があります。このバッファリングを無効にするには、config.ruに下記を追加します。

:::ruby
$stdout.sync = true

Webサーバ

このドキュメントで使用するサンプルアプリケーションでは、GemfileにThinが含まれています。それが環境で利用可能なときに、SinatraはThinを使って実行します。他のWebサーバを指定しない場合、Rackは一般的なWEBrickにフォールバックされます。これはテストのためにはいいのですが、アプリケーションが本番向けに準備ができた段階でThinに切り替えた方がよいでしょう。

トラブルシューティング

アプリケーションをプッシュし、それがクラッシュした場合(heroku pscrashedと表示されます)、何が悪かったのかを見つけるためにログを確認してください。ここではいくつかの一般的な問題を示します。

ソースファイルのrequireに失敗

アプリケーションがソースファイルのrequireを失敗した場合、ローカル環境でRuby 1.9.1または1.8を実行している可能性が高いです。ロードのパスがRuby 1.9では変更されています。Cedarに再度プッシュする前に、ローカルで動作する様にアプリをRuby1.9.2向けに移植してください。

エンコーディングエラー

Ruby 1.9では、より洗練された言語のエンコードのサポートが追加されています。すべてのgemがRuby 1.9で動作するわけではありません(特定のgemに関してはisitruby19を参照)。もし、エンコーディングエラーに遭遇したら、ローカル環境でRuby 1.9.2を使用してアプリケーションを十分にテストできていない可能性があります。Cedarに再度プッシュする前に、ローカルで動作する様にアプリをRuby1.9.2向けに移植してください。

gemが見つからない

アプリケーションにgemの欠落が原因でクラッシュした場合、それがローカルにはインストールされているが、Gemfileに指定されていない可能性があります。**bundle execを使ってローカルでのテストを分離する必要があります。**たとえば、ruby web.rbとは実行せずに、 bundle exec ruby web.rbと実行します。rake db:migrateではなく、bundle exec rake db:migrateと実行します。

別のアプローチとしては、システムにインストールされたgemには絶対に触れないようには空のRVMのgemsetを作成します。

:::term
$ rvm gemset create myapp
$ rvm gemset use myapp

開発/テスト時のgemのランタイム依存

もし、まだデプロイ時にgemが不足しているようでしたら、Bundlerのグループを確認してください。Herokuは、 developmenttestグループは含まない状態でアプリケーションを構築し、アプリケーションが実行するために、これらのグループのいずれかのgemに依存している場合は、グループの外に移動する必要があります。

一つの一般的な例として、RakefileでRSpecタスクを使用する場合があります。Herokuのデプロイで次が表示された場合:

:::term
$ heroku run rake -T
Running `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タスクの条件をを作成して修正します。例えば、

Rakefile

:::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にプッシュします。

Clone this wiki locally