xxxcaqui.log

ツッコミお待ちしています

Rails上で動くCMS LocomotiveCMSを使ってみる。

近々、CMSを構築する必要が出てきたのでLocomotiveを使ってみた。

Locomotiveを選んだ理由は大きく以下の3つ。

  1. Rubyで書かれている
  2. Herokuで動かせる
  3. 管理ページが日本語対応している*1

後々、大きく手を加える予定なので「使い慣れた環境で動くもの」という点を重視して選びました。

Locomotiveとは

LocomotiveはRailsCMSとして使うためのgemです。
オープンソースであり、開発はGitHub上で行われています。

https://github.com/locomotivecms/engine

依存アプリケーションのインストール

Locomotiveは以下の4つに依存しています。

RubyRailsは既にインストールされていると思うので、MongoDBとImagemagickを入れます。*2

Ubuntuの場合こんな感じ。

$ sudo apt-get install mongodb-server imagemagick

Rails, Locomotiveを使ってCMSを構築する

Railsアプリケーションの作成

実際にCMSとして使用するRailsアプリケーションを作成していきます。
ただ、LocomotiveはDBにMongoDBを使用するため、ORMとしてActiveRecordを使用出来ません。そこでActiveRecordを除いた状態でRailsアプリを作成します。

$ rails new new_loco --skip-active-record --skip-test-unit --skip-javascript --skip-bundle

LocomotiveではActiveRecordの代わりにMongoidが使用されます。*3

Gemfileを設定してgemをインストールします。

#~/new_loco/Gemfile
gem 'locomotive_cms', '~> 2.0.1', require: 'locomotive/engine'
gem 'therubyracer', '>= 0.8.2' # Linux only

gem 'unicorn', group: :development
gem 'thin', group: :production

group :assets do
  gem 'compass-rails',  '~> 1.0.2'
  gem 'sass-rails',     '~> 3.2.4'
  gem 'coffee-rails',   '~> 3.2.2'
  gem 'uglifier',       '~> 1.2.4'
end
$ bundle install

Locomotiveのengine用の設定ファイルを生成します。

$ bundle exec rails generate locomotive:install

ただし、上記コマンドの実行が2回目以降の場合、データベースの名前がぶつかって、

==  MakeEditableElementsConsistent: migrating ==
[old_app_name] index (de)
rake aborted!
An error has occurred, all later migrations canceled:

undefined method `walk' for nil:NilClass

とか怒られます。

したがって、先にconfig/mongid.ymlの設定を書き換えてください。

development:
  <<: *defaults
  database: locomotive_dev # Overwite this

locomotive:installコマンドが完了すると、

The Locomotive Engine has been correctly
installed in your Rails application.

  1. Edit the main config files:
    - config/initializers/locomotive.rb
    - config/initializers/carrierwave.rb
    - config/initializers/dragonfly.rb
    - config/mongoid.yml
    - config/devise.yml
    - config/routes.rb

  2. Launch the server
    > bundle exec unicorn_rails

  3. Open your browser
    > open localhost:8080

  4. Follow the installation wizard steps
  5. Enjoy !

と表示されてLocomotiveを使用できるようになります。

$ bundle exec unicorn_rails

して、localhost:8080にアクセスしてみてください。

初期設定画面が立ち上がります。

f:id:xxxcaqui:20130410224428p:plain

Herokuにデプロイする

Heroku上にアプリケーションを作成する

Heroku上にアプリケーションを作成し、bundle installのオプションを設定しておきます。

$ heroku create new-loco
$ heroku config:add BUNDLE_WITHOUT=development:test

Heroku用のgemを入れる

LocomotiveはそのままだとHeroku上で動かないので、Herokuで動かすためのgem locomotive-herokuを入れます。

#Gemfile
gem 'locomotive-heroku', '~> 0.0.2', require: 'locomotive/heroku'
$ bundle install

そして、設定ファイルに記述を追加。
アプリケーション名はまだしも、API keyは他人に見られたくないため、Herokuの環境変数を使います。

#config/initializers/locomotive.rb
config.hosting = {
  target: :heroku,
  api_key: ENV["HEROKU_API_KEY"],
  app_name: ENV["HEROKU_APP_NAME"]
}
$ heroku config:set HEROKU_API_KEY=< your api key >
$ heroku config:set HEROKU_APP_NAME=< your app name >

Amazon S3情報の設定

Herokuアプリケーションのローカルストレージは永続性が保証されないので、ストレージとしてS3を使います。

このあたりはさっき入れたlocomotive-herokuが対応してくれているので、Herokuの環境変数にS3の情報を設定するだけで大丈夫です。*4

$ heroku config:add S3_KEY_ID=<your s3 key id>
$ heroku config:add S3_SECRET_KEY=<your s3 secret key>
$ heroku config:add S3_BUCKET=<your s3 bucket name>
$ heroku config:add S3_BUCKET=<your s3 zone>

S3のゾーンはわかりにくいですが、AWSにログインしてから

S3 Management Console > Properties > Static Website Hosting > Endpoint

で見られます。*5

MongoDBアドオンの設定

HerokuのデフォルトDBはPostgreSQLなので、MongoDBを使えるようにadd-on「MongoHQ」を追加します。

$ heroku addons:add mongohq:sandbox

DB設定ファイルのherokuのuri:をアンコメントし、デフォルトになっているbushidouri:をコメントアウトします。

#config/mongoid.yml
production:
  # heroku
  uri: <%= ENV['MONGOHQ_URL'] %>

  # bushido (mongohq_url will also work)
  # uri: <%= ENV['MONGODB_URL'] %>

ここでの環境変数はadd-on追加時に自動的に設定されています。*6

メールアドオンの設定

メール送信用のadd-on「SendGrid」も一緒に設定しておきます。

$ heroku addons:add sendgrid:starter

メールの設定を行います。
ここでの環境変数も自動的に設定されています。

#config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address:        "smtp.sendgrid.net",
  port:           25,
  authentication: :plain,
  user_name:      ENV["SENDGRID_USERNAME"],
  password:       ENV["SENDGRID_PASSWORD"],
  domain:         ENV["SENDGRID_DOMAIN"]
}

precompile設定

このままHerokuにデプロイすると、asset pipeline周りで弾かれました。

Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       Failed to connect to a master node at localhost:27017

したがって、面倒ですがprecompileしてからデプロイすることにします。

デプロイ時のprecompileを無効化。*7

#config/application.rb
module NewLoco # your app name
  class Application < Rails::Application
    config.assets.initialize_on_precompile = false
  end
end

precompileを実行。

$ bundle exec rake assets:precompile

これで、コンパイル済みのassetsが生成され、デプロイできるようになります。

やったね!

おまけ:Wagonのインストール

LocomotiveにはWagonというユーティリティツールが存在します。

$ gem install locomotivecms_wagon

Locomotiveサイトの作成

先程、インストールしたWagonを使って新規Locomotiveサイトを作成します。

$ wagon init first_loco_site --template bootstrap

これで、Twitter Bootstrap適用済みのfirst_loco_siteという名前の新規サイトが作成されます。*8

なお、現時点でのテンプレートは以下のものがあります。*9

blank 最小限のファイル構成でサイトを作成します。
bootstrap Twitter Bootstrapを使用してサイトを作成します。
foundation Foundationを使用してサイトを作成します。
unzip zip圧縮されたLocomotiveサイトを展開します。*10

サイトが作成できたら、必要なgemをインストールし、ついでにGitでバージョン管理しておきます。

$ cd first_loco_site
$ bundle install
$ git init .
$ git add .
$ git commit -m 'First commit.'

作成したサイトの確認

ここまでで作ったサイトを確認しておきます。

$ buncle exec wagon serve

上記のコマンドでサーバが立ち上がり、0.0.0.0:3333からアクセスできるようになります。*11

f:id:xxxcaqui:20130410190147p:plain

また、app/views/index.liquid.hamlを編集すると、サンプルページが変更されます。サーバの再起動は必要ありません。なお、ログは log/wagon.logに吐き出されます。

*1:ウソです。i18n対応していたので日本語を追加しました。

*2:MongoDBやImagemagickもわりとインストール済みだったりします。

*3:ちなみに、MongoDBはRDBMSではなくドキュメント指向のいわゆるNoSQLなので、ORMではなくODM(Object-Document Mapper)です。

*4:config/carrierwave.rbを設定すれば、CarrierWaveでアクセスできる他のストレージも使用できるみたいです。

*5:見つけるまで結構かかりましたw

*6:heroku config:getで確認できます。

*7:http://guides.rubyonrails.org/asset_pipeline.html

*8:途中でhamlを使うかどうか聞かれるので、テキトーに答えてください。

*9:wagon list_templateコマンドで見れます。

*10:コマンド実行後、zipのパスを要求されます。ローカルまたはhttp, https, ftpで取得可能なURLを指定できます。

*11:RFC1700によると0.0.0.0は「This host on this network. Can only be used as a source address.」とあり、ホストのアドレスを示すらしい。本来は送信元アドレスとしてしか利用できないようだが、Linuxではlocalhostと同義のようでlocalhost:3333でもアクセスできます。ネットワークの勉強しないと。