heroku+sinatra+activerecord+postgresql
ローカルでの準備
環境
- Vigrant with CentOS6.4
- ruby 2.0~
- postgresql9.3
postgresql のインストール
"PostgreSQL Deep Dive: VagrantでPostgreSQL 9.3の動く仮想サーバを自動構築してみる (http://pgsqldeepdive.blogspot.jp/2013/09/vagrant-postgresql93.html)"のとおりにインストール。
データベースの作成
使用する database を作ります。
% sudo -u postgres -i $ psql =# create database testdb; =# \q
次にtableを postgresql で作ります。データベースは .env で指定し、model.rb でdotenv gem を使って読み込ませます。
% vi .env DATABASE_URL = "postgres://localhost/testdb" % vi model.rb require 'dotenv' require 'active_record' Dotenv.load ActiveRecord::Base.establish_connection(ENV['DATABASE_URL']) class Post < ActiveRecord::Base; end
Rakefileではそれを require します:
% vi Rakefile require 'sinatra/activerecord' require 'sinatra/activerecord/rake' require 'rake/clean' require './model'
migration ファイルを作り、migrate をかけテーブルを作成します:
% rake db:create_migration NAME=create_posts .... % vi db/migration/xxxxx_create_posts.rb class CreatePosts < ActiveRecord::Migration def change create_table :posts do |t| t.string :text t.timestamps end end end % rake db:migrate ...
これでローカル上のデータベース作成は完了。念のため確認します:
% psql testdb testdb=> \dt List of relations Schema | Name | Type | Owner --------+-------------------+-------+--------- public | posts | table | vagrant public | schema_migrations | table | vagrant (2 rows) => select * from posts; id | text | created_at | updated_at ----+----------+----------------------------+---------------------------- => \q
ウェブアプリの作成
'localhost:port/' にアクセスされると text: "hoge" なレコードを一つ追加していく簡単なsinatraアプリを作ります。
まずGemfile に使う gem を羅列し、bundler install して Gemfile.lock を作ります。
% vi Gemfile source 'https://rubygems.org' gem 'rake' gem 'sinatra' gem 'sinatra-contrib' gem 'sinatra-activerecord', :require => 'sinatra/activerecord' gem 'dotenv' gem 'activerecord' gem 'pg' % bundle install ...
アプリ本体。こちらをまず先に require 'xxx' 形式で書いてから Gemfile に構成しなおしてもかまいません。
% vi app.rb require 'bundler' Bundler.require require './model' class MyApp < Sinatra::Base configure :development do register Sinatra::Reloader set :bind, '0.0.0.0' end get '/' do Post.create(text: "hoge") erb :show end end __END__ @@show count: <%= Post.count.to_s %> <div> <% Post.all.each do |post| %> <%= post.text %><br> <% end %>
後は普通に config.ru を書き、rackup し、ブラウザ等で確認します:
% vi config.ru require './app' run MyApp % bundle exec rackup & .... % lynx losthost:9292
foreman 起動用ファイルの作成
% vi Procfile web: bundle exec rackup -p $PORT % foreman start & 17:38:52 web.1 | started with pid 3530 .... % curl losthost:5000
サーバーへのデプロイ
バックアップファイルなどをキレイにするため rake clean をかけ、 また.env はサーバー上に置くと変なことになるので gitignore しときます。
% rake clean % vi .gitignore .env
いつもどおりに:
% git init; git add . ; git commit -m init -a % heroku create NAME ...
heroku-postgresql の addon を使います。後は通常の手順です。
% heroku addons:add heroku-postgresql ... % heroku run rake db:migrate ... % git push heroku master ... % heroku ps web.1: up 2014/MM/DD xx:xx:xx (~ 1m ago) % heroku open ....
Tips
restart
データベースをrollback, migrate したりすると停止したりするので restart をかけます。
% heroku ps:restart web Restarting web dynos... done
ローカルからサーバーのデータベースにアクセス
% heroku config して表示される DATABASE_URL の値を .env に入れます。
% heroku config DATABASE_URL: postgres://xxxuser:xxxpassword@@ecxxx.compute-x.amazonaws.com:5432/xxxdatabasename HEROKU_POSTGRESQL_XXXX_URL: postgres://xxxuser:xxxpassword@@ecxxx.compute-x.amazonaws.com:5432/xxxdatabasename LANG: en_US.UTF-8 RACK_ENV: production % vi .env #DATABASE_URL = "postgres://localhost/testdb" DATABASE_URL = "postgres://xxxuser:xxxpassword@@ecxxx.compute-x.amazonaws.com:5432/xxxdatabasename"