ウェブサービスを作っています。

GAE で Rails アプリが作りやすくなっています

追記(2009/11/29 19:26):
Google App Engine 0.0.5 gem では、この記事通り動かすことができなくなっていますのでご注意ください。


google-appengine という gem のおかげで、簡単になっています。XML 書かなくて済みます。
Rails Primer for Google App Engine with JRuby
ところで、この記事通りやってもうまくいかなかったので、自分のやり方を書きます。


Hello world アプリを作ってみます。まず、gem で google-appengine をインストールします。

$ sudo gem install google-appengine

CRuby の gem です。いろいろと関連 gem がインストールされます。
appengine-apis という gem が入っているとこの後うまくいかなくなる気がするので、入っている場合はアンインストールしておいたほうがいいかもしれません。


次に、ふつうに Rails アプリを作ります。

$ rails hello
$ cd hello


RAILS_ROOT に config.ru というファイルを作ります。

require 'appengine-rack'
AppEngine::Rack.configure_app :application => 'hello', :version => 1
# use AppEngine::Rack::AdminRequired

ENV['RAILS_ENV'] = 'appengine'
require 'config/environment'
run ActionController::Dispatcher.new

AppEngine::Rack::configure_app の :application => "hello" の部分は、自分のアプリケーション ID に変更します。
version 要素は、なくても大丈夫です。


開発中などで、管理者のみ公開にしたいときは

# use AppEngine::Rack::AdminRequired

の行をコメントアウトします。
その他 AppEngine::Rack::LoginRequired や AppEngine::Rack::SSLRequired などが use で使えますし、適用範囲の指定もできます。
google-appengine インストール時にインストールされた appengine-rack gem の lib/appengine-rack.rb や appengine-tools gem の spec/config.ru などが参考になると思います。
追記(2009/10/27 17:20):
config.ru の別サンプルを書きました。
Rails on GAE における config.ru サンプル - milk1000cc


アプリ用に gem をインストールします。

$ appcfg.rb gem install rails appengine-apis


ActiveRecord は使わないので config/environment.rb でその旨を記述します。

..
Rails::Initializer.run do |config|
  config.frameworks -= [ :active_record ]
  ..
end
..


続いて、RAILS_ROOT/config/environments に appengine.rb というファイルを作ります。

config.cache_classes = true
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching             = true
config.action_view.cache_template_loading            = true

require 'appengine-apis/logger'
config.logger = AppEngine::Logger.new

上の 4 行は、config/environments/production.rb からコピーしてます。


ふつうに welcome コントローラを作ります。

$ script/generate controller welcome

app/controllers/welcome_controller.rb

class WelcomeController < ApplicationController
  def index
    render :text => 'hello world'
  end
end

config/routes.rb

ActionController::Routing::Routes.draw do |map|
  map.root :controller => "welcome"
  ..
end

RAILS_ROOT/public/index.html は消しておきましょう。


さて、そろそろローカルでテストしてみます。

$ dev_appserver.rb .
=> Booting DevAppServer
=> Press Ctrl-C to shutdown server
=> Downloading jruby-rack...
/opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/lib/appengine-tools/boot.rb:59:in `exec': Operation not supported - java (Errno::E045)
        from /opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/lib/appengine-tools/boot.rb:59:in `exec_jruby'
        from /opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/lib/appengine-tools/boot.rb:35:in `boot_jruby'
        from /opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/lib/appengine-tools/bundler.rb:106:in `convert_config_ru'
        from /opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/lib/appengine-tools/bundler.rb:86:in `bundle'
        from /opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/lib/appengine-tools/bundler.rb:192:in `bundle_app'
        from /opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/lib/appengine-tools/dev_appserver.rb:36:in `run'
        from /opt/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.1/bin/dev_appserver.rb:18
        from /opt/local/bin/dev_appserver.rb:19:in `load'
        from /opt/local/bin/dev_appserver.rb:19

なんかエラー出てます。が、無視してもう 1 回実行すると大丈夫なので無視します...

$ dev_appserver.rb .
=> Booting DevAppServer
=> Press Ctrl-C to shutdown server
=> JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
"appengine-apis/sdk" is deprecated. Use "appengine-sdk"
2009-08-09 10:20:38.690 java[19422:10b] [Java CocoaComponent compatibility mode]: Enabled2009-08-09 10:20:38.691 java[19422:10b] [Java CocoaComponent compatibility mode]: Setting timeout for SWT to 0.100000
JRuby limited openssl loaded. gem install jruby-openssl for full support.http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
"appengine-apis/sdk" is deprecated. Use "appengine-sdk"
The server is running at http://localhost:8080/


http://localhost:8080/

hello world

okです。
ところが、このまま本番サーバにアップすると no such file to load -- appengine-sdk というエラーが出るので、修正する必要があります...


先ほどアプリ用にインストールした gem は RAILS_ROOT/.gems に入っています。ここに appengine-sdk gem を入れます。
ただし、

$ appcfg.rb gem install appengine-sdk

だとエラーが出たので、appcfg.rb を使わずに

$ gem install -i .gems appengine-sdk --no-ri --no-rdoc

で入れます。


appengine-sdk gem を入れると GAE/J の SDK も入るのですが、本番サーバにはアップする必要がないので削除して容量節約に努めます。

$ rm -rf .gems/gems/appengine-sdk-1.2.2/appengine-java-sdk-1.2.2

最後に jar で固めます。

$ cd .gems
$ jar cf ../WEB-INF/lib/gems.jar gems specifications
$ cd (RAILS_ROOT)


これで本番でも動くはずです。

$ appcfg.rb update .

でアップ。http://(app-id).appspot.com/ で確認。


元記事の irb とかうまく動かないし、まだまだ問題は多いですが、そのうちよくなると思います。
ロリポップより安い値段 (というか無料) で Rails アプリが普通に動くとか、すごいです...