Engine Yard Cloudに限りませんがちょっとハマったので。

UTCで動いてるサーバーで、例えば日本からのアクセスが大半で一番空いてる時間が朝5時(よくある)の場合、JST 5時はUTC 20時(前日の)なので集計バッチなどは上記の用な感じにしておく。

EYCでのステージング環境問題ですが、料金シミュレーターで見積もってみたらsmallを一台だけ立ち上げれば6119円だそうなのでEYCにステージング環境を作ってみました。

こんな感じです。

staging環境はRails.envがstagingになります。そんなの大丈夫なのかよとおもいますが、37signalsも色々とenv作ってるようなので予想外のことはそれほど起きないです。

変える必要があるところ

  • database.ymlにstagingを追加する。
  • if Rails.env.production?となってるところをif Rails.env.production? or Rails.env.staging?に変える。
  • s3、CloudFrontにstaging用の設定を追加する(paperclip使ってる場合は要注意)
  • Gemfileでgroup :production doとなってるところをgroup :production, :staging doに変える。

ものに応じてproductionだけでやりたいこと、production or stagingでやりたいことがあるので慎重に選ぶ必要があります。

例えば公式Twitterアカウントで通知する部分や本物の広告配信はproductionだけでやりたいでしょうし、S3を使うかどうかというのはproduction or stagingでやりたい。

リリース作業をCIする

デプロイといっても色んな意味が含まれてて、コンパイル・テスト・パッケージング・リリースをひっくるめてデプロイと言えますが、Railsだと大抵テストのみをさしてデプロイと言う。

実際のRailsアプリはリリースで問題が結構起きるのでこれを含めてCIしたい。

EYCはeyコマンドでリリースするので怖話ではこんな感じ。

弊社の場合はpushされるたびに↓のような通知がくるが、まあいい。

受託開発でEYCを使う場合はステージング環境代金もちゃんと見積りに入れると良いと思います。

Engine Yard Cloudのstagingをどうするか悩んでます。

  1. Engine Yard Cloudにstagingを作る。
  2. さくらVPSとかにstagingを作る。
  3. Engine Yard LocalをさくらVPSに入れる。

1はstagingへのdeployを含めてCIしたいので立ち上げっぱなしではお金が厳しい。

2はEYCへはeyコマンドでdeployし、さくらVPSでへのcapistranoでのdeployになり、環境もかなり違うのでstagingにならない。同じ理由でherokuも微妙。

3はまだやったこと無いが、さくらVPSにVirtualBoxを入れてEYLは実用的なのかわかってない。またeyコマンドでEYLへデプロイが可能かどうかも気になる。

EYCにかぎらず、stagingの話ってあんまりしない。もっとstagingの話がしたい!

追記:Engine Yard Cloudにステージング環境を作る

cronの設定画面から追加しただけじゃ反映されてない。(どうでもいいけどこのRun this commandの欄短すぎやしないかい)

Environmentに変更があったのでこのApplyボタンを押して反映させることを忘れないようにする。

今までは@hrysd謹製のcapistrano-lingrを使ってましたがEYCに移ったのでenginyard gemのdeploy hookを使います。

deployディレクトリの下にフック名でrubyファイルを置くとそれが勝手に実行されるようになっています。

APP_ROOT/ 
   deploy/  
    before_bundle.rb  
    after_bundle.rb  
    before_compile_assets.rb  
    after_compile_assets.rb  
    before_migrate.rb  
    after_migrate.rb  
    before_symlink.rb  
    after_symlink.rb  
    before_restart.rb  
    after_restart.rb 

参照: Use Deploy Hooks : Engine Yard Developer Center

通知はいつでもいいのでafter_restartにしてみました。

# Gemfile:
gem 'lingman', github: 'hrysd/lingman'
# deploy/after_restart.rb
# encoding: utf-8
require 'rubygems'
require 'bundler/setup'
require 'lingman'

Lingman::Updater.update(
  "fjord_assistant", # BOT ID
  "takoroom", # ROOM ID
  "XXXXXXXXXXXXX", # SECRET
  "#{app} を #{environment_name} にデプロイしました。"
)

deployスクリプトはPlain old ruby fileなのでrequire 'bundler/setup'でbundleしたgemにパスを通してもらいます。

Lingrへの通知にはこれまた@hrysdのlingmanを使わせてもらいました。Lingr APIを網羅してないのでまだgemにしたくないようですが、githubから読み込んで使います。

これでイチイチ「怖話、本番環境にデプロイしましたー」とチャットに報告しなくてよくなりました。

アップロード画像に関してはこちら

画像をS3にアップする - komagata

残りのassetsもS3に置いていきます。

# Gemfile:
group :assets do
  gem 'asset_sync'
end
$ rails g asset_sync:install --use-yml --provider=AWS
# conifg/asset_sync.yml:
defaults: &defaults
  fog_provider: 'AWS'
  aws_access_key_id: "XXXXXXXX"
  aws_secret_access_key: "XXXXXXXXXXXXXXX"
  fog_directory: "kowabana-jp"
  fog_region: "ap-northeast-1"
  existing_remote_files: keep

development:
  <<: *defaults
  enabled: false

test:
  <<: *defaults
  enabled: false

staging:
  <<: *defaults
  fog_directory: "staging-kowabana-jp"

production:
  <<: *defaults

これだけでrake assets:precomipleした時にS3にアップしてくれます。便利ですね。

# config/environments/production.rb:
KowabanaJp::Application.configure do
  config.action_controller.asset_host = "//cdn.kowabana.jp"
end

こうするとimage_tagとかasset_pathとかが吐くURLがCDN(CloudFront)になってくれます。

Engine Yard Cloudならではの部分

特に無し。ey deployのデフォルトではrake assets:precompileが走るので特に気にしなくてもアップされます。楽だわあ。

environmentを作る時に選んだタイミング・回数分保存されてます。リンクからmysqldumpの内容がダウンロードできます。分かりやすいですね。

他の環境ではDBバックアップはdumper.ioが超オススメです。

管理画面から簡単に設定できる。怖話では毎日夜中の11時に怖い話をお届けするTwitterボットやランキングの集計にcronを使っている。

この画面から設定したcronjobはAppサーバーのMasterに反映されるようだ。mysqlcheckなど、DBサーバー上で実行したい場合は直接やった方がいいんだろうか。

HerokuのようにSendGridアドオンを使う。

アドオン画面からSendGridを選び、対象のアプリ/environmentを選んでactivateしておく。

Set it upの内容にしたがってey_configというgemを入れておく。これはEYCと連携した各種サービスのIDとかパスワードとかを良いように扱ってくれる。

メールはsendmailでサラッと送りたい気がするが、EC2上のIPはブロックされてたりするのでSendGridやGmailやSESを使うのが無難なようだ。SendGridは無料プランでは1日200通までなので若干不安ではある。

Set it upに書いてあるようにconfig/environments/production.rbに下記を追加する。

config.action_mailer.delivery_method = :smtp
config.action_mailer.default_charset = "utf-8" # NOT FOUND ON RAILS3.1
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
     :authentication => :plain,
     :address => "smtp.sendgrid.net",
     :port => 587,
     :domain => "yourdomain.com",
     :user_name => EY::Config.get(:sendgrid, 'SENDGRID_USERNAME'),
     :password => EY::Config.get(:sendgrid, 'SENDGRID_PASSWORD')
}

EY::Config.getという部分でサーバー上に良い感じに置かれた設定ファイル(実際には/data/app_name/shared/config/ey_services_config_deploy.yml)から値を読みこんでくれる。

ここで罠なのが、config.action_mailer.default_charsetというメソッドはrails3.1以降は存在しないというところだ。うっかりproductionへデプロイするとサイトがエラーになる。stagingというenvironmentを同じ構成で用意し、試しにデプロイしてみてからの方が無難だろう。

弊社(FJORD, LLC)がEngine Yardとパートナーシップ(的なもの)を結んで怖話Engine Yard Cloud(以後EYC)に移行しました。

(飽くまで”的なもの”で、ちゃんとしたパートナーシップはこういうの

トライアルで検討する

トライアルで試した件については以前こちらに書きました。

Engine Yard Cloudを試す - komagata

本契約前に

貧乏会社なので複数台サーバーなんていくら掛かるのか怖い。料金シュミレーターで予め見積もっときました。

さくらVPSから移行したのは複数台構成のためなので、ちょっと奮発してappサーバー2台+dbサーバー1台の構成にしてみました。高けー!

デプロイ

手順はトライアルの時と同じです。ただ、本契約の場合は東京リージョンが選べます。

アクセスしてみる

appサーバー2台あるけど、どのIPにアクセスしたらいいの?と思いましたが、Application Masterの方のSSHのリンクをクリックする時に出るURLにIPがハイフン区切りで出てるのでそこにアクセスします。(この場合は54.249.225.67)

dbの方もそれで直接dbのインスタンスにsshできます。ユーザー名はdeployでした。

アプリをEYCに合わせる

EYCに載せるに当ってアプリを修正しないといけない点が2点ありました。

rubyを1.9.3系にする

EYCはまだruby2.0.0に対応してないので1.9.3系に変更しました。あんまり変わらないだろうと思ってましたが、encodingのmagic commentが無くていくつかエラーが。泣く泣く追加しました。

ユーザーのアップロード画像をS3に移行

これはEYCだからではなく、appサーバーが複数台になるのでユーザーがアップする画像をローカルに保存してたら迷子になります。幸いpaperclipの画像保存先をS3にするのは簡単で1日あれば対応できました。

データベースの移行

$ ssh bodom "mysqldump -udeployer -pXXXXXXX kowabana_production" | ssh db.kowabana.jp "mysql -uroot kowabana" 

これはコマンド1行でOK。sshで入れるとこういうところが楽ですね。EYCのdb名はアプリ名と同じになるようです。mysqldumpは全テーブルロックするのでデータ量の大きなサイトではこういう雑な移行はオススメできません・・・。

railsアプリのdatabase.ymlの接続先は変えなきゃいけないんじゃないの?と思いましたが、EYCのdeployのレシピで良い感じにdatabase.ymlを生成してくれるそうです。便利。

サポートチャット

トライアルの時もお世話になったサポートチャットですが、グローバルの方は平日の8AM PST - 6PM PST(日本では1時から13時)がサポート時間です。

これは豆ですが、Engine Yardの日本法人のトップページのチャットから発信すれば日本人が日本時間で対応してくれます。

感想

まだ移行したばっかりなのでどうなるかわかりませんが、移行作業自体は思ったより早く簡単にできたなと思います。最近セキュリティ周りがキナ臭いのでその辺は安心感がありますね。(最近別の仕事でウィルスに感染したPHPのサイトの調査をやったばかりです。)

オープンネットワークラボにGithubのPJらが来た時のイベントで「初期のGithubはEngine Yardにサーバーを借りていた」という話を聞いてその後の懇親会でいきなり不躾にも「弊社にもサーバー貸してください!」と@yandoさんに無茶振りしたことから始まった話でしたが色々お手数をお掛けしつつ移行できてよかったです。ありがとうございます。