Heroku,Sinatra,Twitter Bootstrapを使ってみました

無事達人出版会様よりきつねさんでもわかるLLVMを公開できました。
それと同時公開を目標に作成したMotiPizzaのサークル公式ページを作成したのでその方法をまとめてみます。
後半の部分の手順忘れてしまったので適当になってますが。

今回のポイントとしてはタイトルの通りデプロイ先としてHerokuを利用し, フレームワークとしてSinatra(ruby), そしてデザイン(CSS)としてTwitter Bottstrapを使ったことです。
Rubyを含めすべて初めて使ったのでそのあたりもついでにまとめておきます。
参考にしたサイトは最後にまとめてあります。

今回作成したページのソースはGitHubにあります。

Rubyの開発環境

Rubyは一度も使ったことなかったので、今回作成するにあたりRuby使おうというのはすぐ決めました。
よくわからないけどちらちら見る単語から判断するにrbenvでRuby本体のバージョン切り替えを行ってGemでパッケージ管理するまで理解しました。

rbenvのインストール方法はいろいろなところを参考にしましたがapt-getでさくっといれました。(debian sidにしかないっぽいです。普通はgithubからいれるみたい)
ruby-buildはrbenvでRubyをインストールするために必要?

$ sudo apt-get install rbenv ruby-build

rbenvを使うためにbashrcやzshrcなどに設定を入れておく必要があるようです。設定後にはログインしなおすなりして設定を有効にしてください。

## zshの場合は.zshrcに以下を追加
eval "$(rbenv init - zsh)"
## bashの場合は.bashrcに以下を追加(?)
eval "$(rbenv init -)"

rbenv入れた後に実際にrubyをインストールしますが、インストールできるrubyのバージョンは以下のコマンドで確認できます。

$ rbenv install

1.9系で一番新しそうなの入れたかったので1.9.3-p194をいれました

$ rbenv install 1.9.3-p194

インストールしたrubyをシステム全体で使う場合にはglobalにバージョン指定します。

$ rbenv global 1.9.3-p194
$ rbenv global
1.9.3-p194

これで好きなバージョンのrubyが使えるようになりましたが、gemを入れるたびにrbenv rehashしないとgemが有効にならないようで、この作業を自動化してくれるgemを入れます。(gem自体のインストール方法は忘れた)

$ sudo gem i rbenv-rehash

Bundler

Bundlerはプロジェクト単位でgemを管理するもので、別の開発環境でも同じ構成を簡単に構築することができるようになります。
特にHerokuではこれを使ってデプロイしてるようです。

bundlerをgemでインストールします。この場合はsudoつけたら違う場所にインストールするからだめ?

$ gem install bundler
$ bundle -v
Bundler version 1.2.3
$ which bundle
/home/sabo/.rbenv/versions/1.9.3-p194/bin/bundle

プロジェクトで使うgemをGemfileで指定します。今回作成したGemfileは以下のようなものです。

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

これをプロジェクトのトップディレクトリに置いた状態で以下のコマンドを実行することで自動的にgemがインストールされます。
特にpathを指定することが重要で、指定path以下にgemがインストールされ、プロジェクトではそこにあるgemしか使わなくなります。

$ bundle install --path vendor/bundler

コマンド実行後に新しいファイルが3つできます。Gemfile.lock以外はコミットしないようにします。

  • .bundle/
    • bundleの設定を保存する場所
    • コミットしない. gitignoreする.
  • Gemfile.lock
    • Gemfileの依存関係により自動的にインストールされるgemの設定もすべて含めたファイル
    • コミットする.
    • Gemfileだけでは依存関係やバージョンが変わる可能性があるため
  • vendor/
    • 実際にgemがインストールされる場所
    • コミットしない. gitignoreする.
    • Gemfile.lockで指定していれば同じ環境ができるはずなので

SinatraHamlを使った開発

RubyフレームワークといえばRailsですがほぼ静的なページ構成になりますし、軽量フレームワークとして有名なSinatraを使うことにしました。
HamlはHTML記述のためのテンプレートです。個人的にはかなり気に入りました。PHPでも欲しいです。

Sinatraの詳しい使い方は公式ページなどを見ると良いですが、簡単なことなら直感的に使い方がわかります。
公式サンプルのコピペですが、これだけで / にアクセスするとindex.hamlを表示するものができます。

require 'sinatra'

get '/' do
  haml :index
end

sinatraの仕様としてhamlなどのテンプレートファイルはviewsディレクトリの中に置く必要があります。
./views/index.haml に以下のように記述したファイルを置きます。

-# coding: UTF-8
!!!
%html
  %head
    %title< MotiPizza
  %body
    HelloWorld!!

hamlではPythonのようにインデントが階層を意味しているのでシンプルな見た目になります。
%divのようにタグは%をつけて記述し、最後に<や>をつけるとHTML生成時の改行を制御できます。
以下のように{}でタグの属性も追加できます。もちろん#{var}のようにrubyの変数をhaml内でも使えます。

%a{:href=>"http://motipizza.com"}< MotiPizza公式ページ

画像やCSSファイル、JavaScriptファイルなどの公開ファイルはpublicディレクトリにおく必要があります。
/public/img/moti.jpg に画像をおいた場合は/img/moti.jpgでアクセスできます。

%img{"src" => "/img/moti.jpg", "alt" => "もち画像"}

hamlで共通部分(レイアウト)を記述するためにはlayout.hamlを置けば良いです。
タイトルやフッターなどは共通で後は個別に異なるという場合に、layout.hamlを使えば共通部分(レイアウト)を記述できます。

%html
  %head
    %title< MotiPizza
  %body
    %div
      =yield
    %footer
      Copyright 2013 MotiPizza

以上のように =yield と書いたところにhamlが展開されるので、index.hamlなどには%div以下だけを書けば良いです。

上記の方法では一番外側しか共通化できないですが、他のhamlファイルをincludeすることで共通の構造を生成できます。
index.hamlなどに以下のように追加します

%div
  = haml :hello

hello.hamlを作成し以下のように記述します。

%p< HelloWorld!!

これで:helloにhello.hamlの内容が展開されます。
今回はtwitterはてブなどのソーシャルボタンをまとめるためにこれを使いました。

foremanを使って動作確認

よくわかってないですがforemanはProcfileに従ってプロセスを起動するものらしいです。
HerokuではProcfileを使うようなのでProcfileを使った状態で動作確認するのが良いでしょう。
もちろんforemanを使わなくても以下のようにコマンドを実行すればSinatraを起動できます。

$ bundle exec ruby web.rb -p 5000

これでSinatraを使って記述した web.rb をポート5000番で起動します。

まずforemanを別途インストールします。

$ gem install foreman

次にProcfileを書きます。Procfileは1行に"アプリケーション名:コマンド"という形式で書きます。アプリケーション名は何でもいいです。
$PORTには5000が入り2行目以降は+100されていくとかなんとか。

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

Procfileを記述したら以下のコマンドを実行することでforemanによりアプリケーションを実行できます。

$ forman start

TwitterBootstrap

Twitter Bootstrapはボタン、フォーム、ナビゲーションなどのテンプレート集みたいなものです。
これを使えばCSSの知識がなくてもそれっぽいデザインができるんじゃないかと思いました。
が、そんなことはぜんぜんないです!
微妙な位置調整やそもそもうまく配置できないときにはCSSさんの出番が来てしまうので、一定の知識は要求されますね。
でもやはり簡単に作れますし、Hamlとも相性が良く記述しやすいので、非常に便利なものだと思いました。

公式のサンプルが結構いろいろ書いてあって参考になるのですが、ちょっと変えようと思うとどうやればいいのかわからないので他のTwitterBootstrapを使ってるところのソースを見てひたすらコピペする作業でした。
FireBugとか使って他人のページをCSS変更したりとか楽しいです。

TwitterBootstrapを使うにはCSSとJSをダウンロードして配置すれば良いですが、
CDNで配信してるところもあるのでそれを使う手もあります。
よくわかってないですが、CDNだと全部入りしかないかもしれません。

.containerを使えばセンタリングされるというのをいろんなところで見るのですが、ほとんどの場合されなくて困りました。
諦めてCSSで位置調整するか、.span4.offset1 などでオフセット指定で調整したりしてます。
あとは、レスポンシブデザインにすると画面サイズ小さくしたときの挙動がよくわからなくて、レイアウトが崩れるので諦めました。

Heroku

HerokuはRuby以外にもJavaなども実行できるホスティングサービスですが、Rubyが一番有名じゃないでしょうか。
実質Railsみたいな印象がありましたが、ちゃんとSinatraも実行できるようです。

詳細はここでは書かないですが、基本的には無料でaddonを使わなければクレジットカードなども登録しなくていいです。
無料のaddon使う場合にもカード登録しないといけないとかなんとか。
あと、1時間(?)アクセスがないとインスタンスが休止するようで次回アクセス時に起動時間が数十秒かかるのが面倒です。
addonで休止しないようにできるみたいです。

細かいHerokuの操作は忘れましたが、Herokuへのデプロイはgitでpushするだけになります。
gitでpush時に必要に応じてテストが行われてProcfile通りにプロセスが実行されます。
既にforemanで動作確認まで済んでいるので、git pushするだけで開発環境と同じ動作が期待できます。
逆に動作が異なるときはgitで管理されている以外のものを使っている状態です。