I choose appfog for Octopress blogging. So how can I setup?

前回のエントリーで、appfogをOctopressのホスティング先に採用したと書いた。今回は実際の設置方法について。

Create new app!

appfogにサインアップした後に、webの管理コンソールを見ると「Create App」というリンクがあるので、ここから新しいアプリを作成することができる。

管理コンソール
管理コンソール
step1
appfog step1

ってやると確かに作れるんだけど、やらない。このまま作成するとruntimeがruby1.9.2になってしまうので。appfogは1.9.3に対応しているので、runtimeを指定してアプリを作成する。これは、webからできなさそうなので、appfog CLIツールを使って実施する。

af the CLI tool

AppFog DocumentationGetting Started > Overviewに書いてある通りにやると、afコマンドをインストールできるので、手順通り実施する。rbenvを使っている場合はrbenv rehashを忘れずに。

install af
$ gem install af
$ rbenv rehash

作成前に、.afignoreファイルを作っておく。これは、.gitignoreと同じようなファイルで、デプロイ時にアップロードを除外するファイルやディレクトリを指定しておくもの。Getting Started > AF CLI Tool > .afignoreに説明が書いてある。

af push to create new app

Octopressディレクトリでaf pushを実行すると、アプリが作成できる。が、最初にやった時はエラーが出て失敗したwwww

このエラーはよく出るので、こんなところでめげてはいけない。このエラー、次の期末試験にも出ますからね。

create new app
$ cd blog-satooshi-jp
$ af push --runtime ruby193
Would you like to deploy from the current directory? [Yn]: Y
Detected a Rack Application, is this correct? [Yn]: n
1: Rails
2: Spring
3: Grails
4: Lift
5: JavaWeb
6: Standalone
7: Sinatra
8: Node
9: PHP
10: Erlang/OTP Rebar
11: WSGI
12: Django
13: Rack
14: Play
Select Application Type: 7
Selected Sinatra Application
1: AWS US East - Virginia
2: AWS EU West - Ireland
3: AWS Asia SE - Singapore
4: Rackspace AZ 1 - Dallas
5: HP AZ 2 - Las Vegas
Select Infrastructure: 3
Application Deployed URL [blog-satooshi-jp.ap01.aws.af.cm]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [128M]: 512M
How many instances? [1]: 1
Create services to bind to 'blog-satooshi-jp'? [yN]: N
Would you like to save this configuration? [yN]: Y
Manifest written to manifest.yml.
Creating Application: OK
Uploading Application:
Checking for available resources: OK
Processing resources: OK
Packing application: OK
Uploading (1M): OK
Push Status: OK
Staging Application 'blog-satooshi-jp': ..........................................…
HTTP exception: RestClient::ServerBrokeConnection:Server broke connection:

もしこのエラーが出ても、アプリの作成は出来ているはずなので、webの管理コンソールからアプリを起動させてやればいい。このコマンドが完了すると、manifest.ymlというファイルが出来上がっているはずだ。説明はGetting Started > AF CLI Tool > Manifestsにある通り。今回は特に必要ないが、構成を使い回す時に便利らしい。

manifest.yml
---
applications:
.:
name: blog-satooshi-jp
framework:
name: sinatra
info:
mem: 128M
description: Sinatra Application
exec:
infra: ap-aws
url: ${name}.${target-base}
mem: 512M
instances: 1

Oops! Octopress can't work!

herokuで動かしていたのは、Octopressをgit cloneしたものそのままのコードだった。しかし、appfogではそのままではエラーが発生し、アプリが起動しなかった。rubyはよく分かってないが、appfogにアプリを作成した直後のapp.rbには、こんなコードがあった。

app.rb
require 'sinatra'
set :protection, except: :ip_spoofing
get '/' do
erb :index
end

どうやらこのファイルにルーティングするコードを書いておけばいいらしい。git clone直後のOctopressのconfig.ruはこうなっている。

config.ru
require 'bundler/setup'
require 'sinatra/base'
# The project root directory
$root = ::File.dirname(__FILE__)
class SinatraStaticServer < Sinatra::Base
get(/.+/) do
send_sinatra_file(request.path) {404}
end
not_found do
send_sinatra_file('404.html') {"Sorry, I cannot find #{request.path}"}
end
def send_sinatra_file(path, &missing_file_block)
file_path = File.join(File.dirname(__FILE__), 'public', path)
file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i
File.exist?(file_path) ? send_file(file_path) : missing_file_block.call
end
end
run SinatraStaticServer

OctopressのコードではSinatraを継承してルーティングをしていたようだ。なので、このSinatraStaticServerクラスの中身をapp.rbに直接書くと、無事にアプリが起動するようになった。

app.rb
require 'bundler/setup'
require 'sinatra'
# The project root directory
$root = ::File.dirname(__FILE__)
get(/.+/) do
send_sinatra_file(request.path) {404}
end
not_found do
send_sinatra_file('404.html') {"Sorry, I cannot find #{request.path}"}
end
def send_sinatra_file(path, &missing_file_block)
file_path = File.join(File.dirname(__FILE__), 'public', path)
file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i
File.exist?(file_path) ? send_file(file_path) : missing_file_block.call
end

Great! now I can setup Octopress on appfog. What's the next?

ここまでの手順で、アプリの設定が完了した。編集後のデプロイはaf updateコマンドで実行できる。

af update
# my app
$ cd blog-satooshi-jp
# new post
$ rake new_post['setup-octopress-on-appfog']
mkdir -p source/_posts
Creating new post: source/_posts/2013-02-22-setup-octopress-on-appfog.markdown
# commit to git repository
$ git add .
$ git commit -m "add new post"
$ git push origin master
# deploy
$ af update
Updating application 'blog-satooshi-jp'...
Uploading Application:
Checking for available resources: OK
Processing resources: OK
Packing application: OK
Uploading (151K): OK
Push Status: OK
Stopping Application 'blog-satooshi-jp': OK
Staging Application 'blog-satooshi-jp': OK
Starting Application 'blog-satooshi-jp': OK

Conclusion: appfog is faster than heroku for Japanese blogger, right?

前回のエントリーにも書いたが、appfogの方が日本に近いシンガポールリージョンを選択できるため、herokuよりもレスポンスが速い。しかし、今回のセットアップ中に何度もエラーが発生していたのが若干気がかりだ。何度かデプロイしてみると、エラーの発生が収まっていった。ちなみに、デプロイはherokuの方が速く終わる。appfogはgitを使わないため、githubなりbitbucketでバージョン管理が必要である。