HerokuでSQLiteを使ってはいけない理由
なぜHerokuでSQLiteを使ってはいけないか。理由は以下の2つです。- HerokuのCedar Stackはephemeral filesystemを持っており、一見ファイルの読み書きができるように見えるが、一日に一度すべてクリアされる。このためSQLiteで保存したデータも毎日失われてしまう。
- もしHerokuのファイルシステムが永続的にデータを保持したとしても別の問題がある。SQLiteはサービス機能を持っていないため各dynoの間でデータを共有することができず、それぞれ固有のDBを保持しているように振る舞ってしまう。
今回YesodチュートリアルのYosogアプリで利用するデータベースをSQLiteからPostgreSQLに移行しました。その手順を紹介しておきます。
ローカル(mac)環境でのPostgres対応
まずローカル環境で動作しないことにはサーバ上で動作するはずがない、ということで、mac上のDevelopment環境でPostgreSQLを利用する手順を記載しておきます。Yesodチュートリアルのサンプル(Yosogアプリ)をローカル環境でPostgreSQL上で動作させるには以下の修正が必要でした。yesod initコマンド実行時に利用DBとしてsqliteでなくpostgresqlを選択すれば、ここで述べるのSQLiteからPostgreSQLへの変更手順は不要になります。
- SQLite環境をPostgreSQL環境に変更
- Application.hsのdbconfをSQLiteからPostgreSQLに
- Settings.hsのPersistentConfをSQLiteからPostgreSQLに (その1)
- Yosog.cabalのbuild-dependsをpersistent-sqliteからpersistent-postgresに (その1)
- config/postgresql.ymlの準備
- MacPortsでpostgresql93をインストールする
- postgresql93パッケージをインストール
- DBインスタンスの生成(serverのinstall時の指示に従う)
- サーバーの起動
- Yosogアプリが利用するDBを生成する
- ユーザーとデータベースの生成 自動生成されるconfig/postgres.ymlを確認するとYosogユーザーでYosogデータベースにアクセスする設定になっています。このため以下のコマンドでユーザーとデータベースを作成しておきます。
- PostgreSQL対応したYosogアプリの起動
- dbconf <- withYamlEnvironment "config/sqlite.yml" (appEnv conf)
+ dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)
-import Database.Persist.Sqlite (SqliteConf)
+import Database.Persist.Postgresql (PostgresConf)
(その2)
-type PersistConf = SqliteConf
+type PersistConf = PostgresConf
- , persistent-sqlite >= 1.3 && < 1.4
+ , persistent-postgresql >= 1.3 && < 1.4
(その2)
- , persistent-sqlite
+ , persistent-postgresql
Default: &defaults
user: Yosog
password: Yosog
host: localhost
port: 5432
database: Yosog
poolsize: 10
Development:
<<: *defaults
Testing:
database: Yosog_test
<<: *defaults
Staging:
database: Yosog_staging
poolsize: 100
<<: *defaults
Production:
database: Yosog_production
poolsize: 100
<<: *defaults
% sudo port install postgresql93
% sudo port install postgresql93-server
% sudo port select postgresql postgresql93
% sudo mkdir -p /opt/local/var/db/postgresql93/defaultdb
% sudo chown postgres:postgres /opt/local/var/db/postgresql93/defaultdb
% sudo su postgres -c '/opt/local/lib/postgresql93/bin/initdb -D /opt/local/var/db/postgresql93/defaultdb'
% sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql93-server.plist
% sudo launchctl start org.macports.postgresql93-server
% createuser -U postgres -P Yosog
% createdb -U postgres Yosog
ユーザーとデータベースが作成されていないと、Yosogアプリ起動時に以下のエラーになります。
Yosog: SqlError {sqlState = "", sqlExecStatus = FatalError, sqlErrorMsg = "FATAL: role \"Yosog\" does not exist\n", sqlErrorDetail = "", sqlErrorHint = ""}
% cabal run -- Development
HerokuにPostgreSQL対応版Haskell/Yesodアプリをdeployする
PostgreSQLを利用する手順はRuby on Rails上であればHerokuのドキュメントで紹介されています。ここではHaskellのYesodフレームワーク上でPostgreSQLを利用するサーバーをHerokuにデプロイするための手順を示しておきます。- postgresqlアドオンの登録&接続情報の確認
- postgresqlアドオン登録
- DB情報の確認
- 接続情報の確認
- 接続情報の反映と接続確認
- config/postgresql.ymlの編集 接続情報で確認した、dbname, host, user, passwordをpostgresql.ymlのProduction:の設定に反映します。
- postgresql対応版サーバーのdeploy
- psqlを用いた接続確認(おまけ) 以下のコマンドでPCからadonしたPostgreSQLのDBに接続することができます。postgresql.ymlのDevelopment:欄に同様の設定をすればアプリ本体はPC上、DBはサーバー上の組み合わせで動作確認することもできます。
% heroku addons:add heroku-postgresql:dev
% heroku pg:info
=== HEROKU_POSTGRESQL_IVORY_URL
Plan: Dev
Status: available
Connections: 0
PG Version: 9.3.3
Created: 2014-03-12 15:42 UTC
Data Size: 6.4 MB
Tables: 0
Rows: 0/10000 (In compliance)
Fork/Follow: Unsupported
Rollback: Unsupported
% heroku pg:credentials HEROKU_POSTGRESQL_IVORY_URL
Connection info string:
"dbname=ddddd host=aaa-11-222-33-44.compute-1.amazonaws.com port=5432 user=uuuuu password=XXXXX sslmode=require"
Connection URL:
postgres://uuuuu:XXXXX@aaa-11-222-33-44.compute-1.amazonaws.com:5432/ddddd
--- a/config/postgresql.yml
+++ b/config/postgresql.yml
@@ -19,6 +19,10 @@ Staging:
<<: *defaults
Production:
- database: Yosog_production
+ user: uuuuu
+ password: XXXXX
+ host: aaa-11-222-33-44.compute-1.amazonaws.com
+ port: 5432
+ database: ddddd
poolsize: 100
<< *defaults
% git commit -m "- use postgersql instead of sqlite." .
% git push heroku master
% heroku open
% psql -h aaa-11-222-33-44.compute-1.amazonaws.com -p 5432 -U uuuuu DDDDD
ddddd> \d
List of relations
Schema | Name | Type | Owner
--------+----------------+----------+----------------
public | article | table | uuuuu
public | article_id_seq | sequence | uuuuu
public | email | table | uuuuu
public | email_id_seq | sequence | uuuuu
public | user | table | uuuuu
public | user_id_seq | sequence | uuuuu
(6 rows)
ここまでの修正はGitHubにコミット済みです。
https://github.com/kurokawh/Yosog/tree/Yosog_PostgreSQL
メモ:ローカルリポジトリの変更をリモートのmaster以外の別ブランチにプッシュするには、以下のコマンドを実行する。
% git push origin master:Yosog_PostgreSQL
Counting objects: 24, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 2.02 KiB | 0 bytes/s, done.
Total 18 (delta 12), reused 0 (delta 0)
To https://kurokawh@github.com/kurokawh/Yosog.git
be68e29..8a25b29 master -> Yosog_PostgreSQL
% git branch -r
origin/Yosog_PostgreSQL
origin/master
参考にした情報:
- macへのPostgreSQLのセットアップ
- YesodでのPostgreSQLの利用
- https://github.com/yesodweb/yesod/wiki/Setting-up-PostgreSQL
- http://d.hatena.ne.jp/asakamirai/20120429/1335710141
- HerokuでPostgreSQLを利用する手順
- https://devcenter.heroku.com/articles/heroku-postgresql
- https://postgres.heroku.com/blog/past/2013/9/9/postgres_93_now_available/
- http://qiita.com/emadurandal/items/b955a4eaa273529ebba0
- gitにおけるリモートブランチの扱い
0 件のコメント:
コメントを投稿