kurukuru-papaのブログ

主に、ソフトウェア開発に関連したメモを書き溜めたいと思います。

GAE/JRuby/Rails2でデモアプリ

前回のエントリーに引き続きGAE/JRubyで、Webアプリを作ってみます。今度はRails2を使ってみました。

GAE上でRailsを動かす方法は、バージョンや環境によって、いくつかの方法があるようで、上手く理解できませんでした。でも苦労して何とか動かすことができました。ネット上に有用な情報を書かれていた皆さんに感謝です!

手順概要

google-appengineがインストール済みの状態からの手順です。

  1. ライブラリのインストール
  2. スケルトン作成
  3. ローカルPC環境で動作確認
  4. config.ruファイル編集
  5. データストア作成
  6. ローカルPC環境で動作確認
  7. GAEへデプロイ
  8. GAE環境で動作確認
手順詳細

次のページを参考にしました。Unix系の記述を、Windows用に変更したぐらいで、ほぼそのまま実施できました。

まずは、必要なライブラリをインストールします。私の場合、次のバージョンがインストールされました。

>gem install appengine-tools --pre
>gem install rails rails_dm_datastore
>gem install activerecord-nulldb-adapter

スケルトンは、下記URLから取得するスクリプトで作成するのですが、このスクリプトはUNIX系環境用です。Windows環境で動作させるため、手を加えました。変更方法は、の内容をほぼそのまま流用させて頂きました。

オリジナルのスクリプト

http://appengine-jruby.googlecode.com/hg/demos/rails2/rails2_appengine.rb

Windows環境用に編集したスクリプト(rails2_appengine_edit.rb)

#!/usr/bin/ruby
#
# Copyright:: Copyright 2009 Google Inc.
# Original Author:: John Woodell (mailto:woodie@google.com)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'fileutils'
require 'open-uri'

def download(url, dest_file_name)
  open(url) do |src|
    open(dest_file_name, "wb") { |dest| dest.write(src.read) }
  end 
end

FILE_BASE = 'http://appengine-jruby.googlecode.com/hg/demos/rails2/'
MOD_FILES = %w{ app/controllers/rails/info_controller.rb config/boot_rb
                config/environment_rb config/gae_boot_patch.rb
                config/initializers/gae_init_patch.rb config/database.yml
                config/initializers/session_store_rb config.ru }

# Install Rails 2.3.5
FileUtils.touch 'config.ru'
download("#{FILE_BASE}Gemfile", "Gemfile")
system 'appcfg.rb.bat bundle --update .'

# Remove dups and generate Rails app
#FileUtils.rm 'public/robots.txt'
system 'appcfg.rb.bat run -rthread bin/rails .'

# Fetch configuration files
FileUtils.mkdir_p 'app/controllers/rails'
MOD_FILES.each { |path| download("#{FILE_BASE}#{path}", "#{path}") }

# Merge configs into boot.rb
open("boot", "wb") do |dest|
  open("config/boot.rb") do |src| dest.write(src.readlines[0,108]) end
  open("config/boot_rb") do |src| dest.write(src.read) end
  open("config/boot.rb") do |src| dest.write(src.readlines[-3,3]) end
end
FileUtils.rm 'config/boot_rb'
FileUtils.mv 'boot', 'config/boot.rb'

# Merge configs into environment.rb
open("conf", "wb") do |dest|
  open("config/environment.rb") do |src| dest.write(src.readlines[0,30]) end
  open("config/environment_rb") do |src| dest.write(src.read) end
  open("config/environment.rb") do |src| dest.write(src.readlines[-12, 12]) end
end
FileUtils.rm 'config/environment_rb'
FileUtils.mv 'conf', 'config/environment.rb'

# Merge session_store initializer
open("config/initializers/session_store.rb", "ab") do |dest|
  open("config/initializers/session_store_rb") do |src| dest.write(src.read) end
end
FileUtils.rm 'config/initializers/session_store_rb'

# install the nulldb adapter
system 'ruby script/plugin install http://svn.avdi.org/nulldb/trunk/'
puts "##"
puts "## Now type 'dev_appserver.rb .'"
puts "##"

Webアプリ用ディレクトリを作成し、先程編集したスクリプトでスケルトンを作成します。これで、必要なファイルやライブラリが色々構築されました。(途中、robots.txtファイルの上書き確認が出ますが、Yesで進めました。)

>mkdir railstest
>cd railstest
>rails2_appengine_edit.rb

とりあえずこの段階で、Webアプリの起動を確認しておきます。私の環境では、デフォルトポート8080使用中のため、3000ポートにしています。

>dev_appserver.rb --port=3000 .

次のURLを開いて動作していることを確認しました。

http://localhost:3000/
http://localhost:3000/rails/info/properties

config.ruファイルの「application」とバージョンの「1」を、自分のGAE環境に合わせます。

AppEngine::Rack.configure_app(
    :application => 'application-id',
    :precompilation_enabled => true,
    :sessions_enabled => true,
    :version => "1")

1つのエンティティへデータ追加/変更/削除する処理を作成します。とは言っても自動生成コマンドを打つだけです。

>ruby script/generate scaffold user user_id:string email:string -f --skip-migration
>ruby script/generate dd_model user user_id:string email:string -f

これだけで出来てしまいました。ローカルPC環境で動作確認してみます。

>dev_appserver.rb --port=3000 .

次のURLへアクセスし、データの一覧が表示され、データの新規作成/変更/削除処理も正常に動作することを確認しました。

http://localhost:3000/users/

いつも通りデプロイします。

>appcfg.rb update .

ブラウザから、次のURLでアクセスし、動作することを確認し、完成です。「application-id」は適宜読み替えます。

http://application-id.appspot.com/users/
苦労話

GAE上でJavaが動くようになってから、JRubyを使用したRails環境構築を行ってみた人は結構いるようで、さらにその方法もいくつかあるようです。

初期の頃は、GAEへデプロイできるファイルの数が1000件までという壁をどう乗り越えるかが環境構築のポイントだったようです。Railsの場合、スケルトンを作成しただけで、1000件を超えてしまうので、これをJARにアーカイブして、デプロイしていたようです。

その後、rails_on_gaeというプラグインが作成されたようですが、私の環境では上手く動作しませんでした。たぶん、UNIX系/Windows系の違いや、CRuby/JRubyの違い、Railsのバージョンの違いがあるのでしょう。

で、最終的には今回まとめた方法で動作させることが出来ました。

動作環境
  • OS : Windows 7
  • Ruby : ActiveRuby 1.8.7 (2010-01-10 patchlevel 249) [i386-mswin32]
  • google-appengine : Version 0.0.9