Heroku に database.yml を自動生成させて PostgreSQL に接続しようとしたけどエラー: "Could not detect rake tasks"

f:id:syonx:20140418234929p:plain

Writing config/database.yml to read from DATABASE_URL
Could not detect rake tasks
ensure you can run $ bundle exec rake -P against your app with no environment variables present
and using the production group of your Gemfile.
This may be intentional, if you expected rake tasks to be run
cancel the build (CTRL+C) and fix the error then commit the fix:
rake aborted!
(config/database.yml): mapping values are not allowed in this context at line 22 column 13

何をやろうとしたか

Heroku で公開している Sinatra アプリで PostgreSQL を使っていたが、database.ymlファイルをそのまま GitHub に push していた。認証情報まで入っていたのでこれはよろしくないと判断し削除&.gitignoreに追加。データベースのパスワードは変更できないようだったので Heroku 上にある既存のデータベースを消して再作成。database.ymlconfigディレクトリが存在する場合にデプロイ時に Heroku が自動生成するとのこと*1*2なので、それに任せようとした。ローカルからも Heroku 上の新しいデータベースに接続先を指定しアプリの動作確認ができたので Heroku に push したところ上記のエラーが発生。

環境

  • Using Ruby version: ruby-1.9.3
  • heroku-toolbelt/3.6.0 (x86_64-darwin10.8.0) ruby/1.9.3

試したこと (1) 失敗

$ heroku labs:enable user-env-compile
 !    No such feature: user-env-compile

ん?

試したこと (2) 失敗

(Gemfile)
ruby "2.0.0"

結果変わらず。∩( ・ω・)∩

試したこと (3) 成功!!

ずっと "Could not detect rake tasks" が本件を特定するためのメッセージかと思ってこれでググっていたけど、ふと "Writing config/database.yml to read from DATABASE_URL" でググったらでてきたこの記事の内容を試して解決。ログメッセージの切れ目がわかりにくくて、前後に相関があるかどうか謎だわ。

Sinatraだからか、ERBは読み込めていたので以下のとおり書き換えた。

- dbconfig = YAML.load(File.read('config/database.yml'))
+ dbconfig = YAML.load(ERB.new(File.read('config/database.yml')).result)

エラーは解消したけど、原因の理解ができていないし、Heroku 的に期待する記述なのか不安。まぁ動くからいいか!

追記(2014/09): 更に別の原因でエラー発生

別のアプリを作って Heroku にデプロイしようとしたら、まーた同じ所でエラー。
ググったら自分で書いたこの記事が引っかかるし何やってんだ俺状態。

f:id:syonx:20140928134334p:plain

rake aborted!
No such file or directory @ rb_sysopen - config/database.yml

この時はconfigディレクトリにローカル用のdatabase.yml(.gitignoreで無視)だけがあって、そのせいで Heroku 上では何もないディレクトリ認定されて破棄されているようだった。ちなみにそれを確かめた手段は以下のとおり。

$ heroku run ls
Running `ls` attached to terminal... up, run.5151
app.rb     bin        db       Gemfile.lock  Rakefile   tmp     vendor
ar_env.rb  config.ru  Gemfile  Procfile      README.md  unicorn.rb  views

なので、.gitkeepを作ってディレクトリをキープ!

$ touch config/.gitkeep

無事デプロイ成功しました。

追記(2015/09): Herokuの仕様が変わってた

またしても1年前と同じエラーにハマる。そして新事実発覚!

ActiveRecord 4.1 以降を使っている場合は config/database.yml の生成をしませんよって。プールサイズなどのオプションを開発者が設定できるようにするためのようです。そして “Change effective on 31 August 2015” とはなんとタイムリーな。

ということで、解決方法としては接続情報を消した config/database.yml を Heroku に渡すことです。 空ファイルをアップしてみたら adapter が指定されてないって言われたので、こんな感じに書いておけばよいと思います。

production:
  adapter: postgresql
  encoding: unicode
  host:
  database:
  username:
  port:
  password:

Enjoy!