sinatra/activerecordを使ってDB操作するプログラムをHerokuへアップロードする際のメモ。
Herokuでアカウントを作っていることが前提。
Herokuの設定
まず、Herokuにpostgresqlをアドオンする。
Herokuのマイページにログインして、「Add-ons」タブをクリックして、Heroku Postgres
を選択するとアドオンできる。Hobby Devプランだと無料で20コネクション、1万行まで利用できる。
アドオンすると、HEROKU_POSTGRESQL_(COLOR)_URL
というデータベース名(ショートカット名)が割り当てられる。
ちなみにローカルマシンの端末から下記コマンドでもアドオンできる。
$ heroku addons:add heroku-postgresql
...
Attached as HEROKU_POSTGRESQL_YELLOW_URL
Database has been created and is available
....
次に、Herokuでは、HEROKU_POSTGRESQL_(COLOR)_URL
をDATABASE_URL
にマッチングすることを推奨しているので、その通りにする。コマンドは以下。
$ heroku pg:promote HEROKU_POSTGRESQL_(COLOR)_URL
これで、一旦HerokuのPostgresqlの設定を確認する。
$ heroku config
=== herokuapp Config Vars
DATABASE_URL: postgres://〜
HEROKU_POSTGRESQL_(COLOR)_URL: postgres://〜
....
となっていればOK。
ちなみに、postgresのURLの意味は
postgres://username:password@host:port/databasename
DBの接続設定とマイグレーション設定
Activerecordを使って、DBの接続設定を行い、マイグレーションしてDBテーブルを作成する。
事前に$bundle exec rake db:create_migration
でマイグレーション用ファイルを生成しておきましょう。
まず、Activerecordの接続設定を行う。先ほど設定してDATABASE_URL
を使う。ローカルの開発環境のDB接続設定も合わせてURL表記にして、||でつなげておく。
もしくは、ローカル環境の環境変数にもDATABASE_URL
を設定しておいてもよい。
ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'sqlite3://localhost/***.db')
ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'postgresql://username:password@localhost:5432/databasename')
require 'dotenv' # .envファイルを読み込めるgem
Dotenv.load
ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
HerokuはDB接続を自動でコネクションを切断しないため、数回(5回?)のアクセスで、ActiveRecord::ConnectionTimeoutError
が発生して、Internal Server Error
となる。ソース内でconnectionを切断するように設定する必要あり。ひとまず、config.ruにActiveRecord::ConnectionAdapters::ConnectionManagement
を読み込ませておくと解決する。詳細は勉強中です。
require './app'
use ActiveRecord::ConnectionAdapters::ConnectionManagement
run Sinatra::Application
HerokuへのアップロードとDBマイグレーション
ここまでできたら、Herokuへアップロード。その前に、.gitignore
にアップロードしないファイルを記述しておく。
最低限以下3つは書いておくと良い。
/vendor/bundle
/.DS_Store
/.env
$ git add .
$ git commit -m 'comment'
$ git push heroku master
アップロードしたら、HerokuのDBをマイグレーションする。
$ heroku run bundle exec rake db:migrate
これでOK。マイグレーションには、sinatra/activerecord/rake
を使うので、bundle exec
を指定しないとエラーとなる。
注意点(ハマったこと)
-
最初は
database.yml
を使おうとしたが、どうやらHerokuでは、database.yml
を自動で生成するらしく、手動設定しても意味が無いみたい。結局、URL指定のやり方しかできなかった。 -
Heroku上でのマイグレーションは、ちゃんと
bundle exec
しましょう。 -
ローカル環境では、ActiveRecordのコネクションを自動切断してくれるが、heroku-postgresは自動切断してくれない。自分でコネクション切断処理を書かないとダメ。これに一番ハマった!!
-
pushと同時に
bundle install
をするらしく、gemのバージョンを揃えるにはGemfile
にバージョンもちゃんと指定しておく必要あり。 -
.gitignore
は、一度commitしたものには反映されないので、一旦$git rm --cached
しておく必要あり。gitで管理しているファイル一覧を見るコマンド$git ls-files
で内容を確認しましょう。 -
テーブルを作り直す場合は、一旦DBを消去する必要あり。
$ $heroku pg:reset DATABASE_URL --confirm app
-
Herokuでは
sinatra/reloader
が使えない。当たり前ではあるが。
ローカルでは利用したいので、以下のようにしてみた。
if(ENV['RACK_ENV']=='development')
require 'sinatra/reloader'
end
その他
Herokuでよく使うコマンド。
-
Herokuのタイムゾーンを東京にする。
$ heroku config:add TZ=Asia/Tokyo
-
Herokuのログを見る。
$ heroku logs
お世話になったサイト
-
Heroku Dev Center
https://devcenter.heroku.com/articles/heroku-postgresql -
Sinatra×HerokuのDB設定をいい感じにする。
http://blog.notsobad.jp/post/60131290938/sinatra-heroku-db -
公開したくない情報はdotenvにしまってしまう
http://shuzo-kino.hateblo.jp/entry/2014/04/15/225517 -
herokuのデータベースをリセット/リストア/再構築する
http://qiita.com/quattro_4/items/a2eb3618207e21ca00d3 -
"Deprecation warning: Database connections will not be closed automatically" #59
https://github.com/puma/puma/issues/59