PostgreSQLを使用したSpringBootアプリをherokuにデプロイする際の注意点

IT, Java

PostgreSQLを使用したSpringBootアプリを作成したので、
herokuにデプロイしようとした所、死ぬほどはまりました。
十時間を超える試行錯誤の末、
なんとかデプロイできたので未来の自分のために注意点を記録しておきます。

Githubにアップするための準備

ソースはGithubにアップするので、
datasourceUrl等は公開しても問題ないようにしなければなりません。
なので環境変数から取得するようにします。

application.yml、
application.propertiesのどちらでも
${hoge}で環境変数が取得できます。

エクリプスの環境変数設定

エクリプスで実行する際の環境変数の設定ですが、
対象アプリの実行→実行の構成→環境から設定できます。

ここで設定した値がymlの${hoge}に入ってきます。

herokuの環境変数設定

herokuアプリのページ→Setting→Config Vars
から環境変数を設定できます。
herokuにpostgresqlを設定している場合、
DATABASE_URLが自動的にセットされています。
このDATABASE_URLが罠でした。
これを単純にdatasourceUrlに設定すれば繋がるのでは?
と感じた僕の予感は大外れでした。
むしろこれを流用しようとすればするほどドツボにハマります。

application.ymlの設定値の解説

driverClassNameはpostgresql使うならorg.postgresql.Driverを指定すればOKです。

datasourceUrlはjdbc:postgresql://ホスト名/DB名?sslmode=requireという形式で指定する必要があります。
jdbc:postgresではなくjdbc:postgresqlであることに注意しましょう。
というのも、先ほど自動的にセットされるHeroku環境変数DATABASE_URLが罠と言いましたが、
DATABASE_URLはpostgres://ユーザー名:パスワード@ホスト名:5432/DB名という形式になっています。
これをコピペするとjdbc:postgresになりやすいので注意してください。
それでは正常に動作しません。
herokuのpostgresqlはSSL通信ではないと繋がらないので?sslmode=requireが必要になります。
これがないと動きません。

さて、僕が最もハマったのだ次の注意点です。
?sslmode=require は環境変数に含むと正常に動作しません。
例を見ながら解説します。

urlに環境変数${dburl}を指定しています。
dburl=jdbc:postgresql://ホスト名/DB名?sslmode=require
上記のように環境変数をセットすると一見、うまく動きそうな気がしますがNGです。
環境変数内に?sslmode=requireを書いてはいけません。
かならずapplication.ymlに直接書くようにしてください。

usernameとpasswordはそれぞれherokuの設定値を環境変数にセットしてください。

heroku環境変数設定値

僕がapplication.ymlで使用している環境変数の設定値を解説します。
といってもherokuのpostgresqlの設定値を環境変数にセットしているだけです。
herokuのpostgresqlの設定値は
herokuアプリ→Resources→Add-onsのheroku-postgresql→Setting→DatabaseCredentialsで確認できます。
${hostname}はpostgresqlのHost名です。
${dbname}はpostgresqlのDB名です。
${username}はpostgresqlのユーザー名です。
${password}はpostgresqlのパスワードです。
DatabaseCredentialsで確認できる値をそのまま使用しています。

デプロイまでの流れ

1、Herokuにアプリを作成
2、Herokuのアプリで使用するPotgresqlを作成。
3、アプリで使用するデータをHerokuのPotgresqlにInsert。
4、Herokuの環境変数にPotgresql接続情報などをセット。
5、ローカルでアプリを作成し、エクリプスに環境変数をセット。
6、ローカルアプリを起動し、HerokuのPostgresqlに接続できるか確認。
7、問題なければローカルアプリをHerokuにPUSH。

その他の問題

なぜかHerokuだとMybatisがうまく動作しませんでした。
ローカルでSpringBootアプリを起動し、
MybatisによってHerokuのPostgresqlに接続できることを確認しました。
データの取得も問題ないことを確認しています。
しかし、HerokuにPushし動作させると、
Mapperが見つからないとエラーが出ます。
結局、調査しても原因がわからないためギブアップしました。
諦めてJPAを使用した所、何の問題もなく動作しています。
なんでや……。

まとめ

application.ymlにおける環境変数の使用方法。
HerokuのPostgresqlに対するdatasourceUrlの設定方法。
上記二つにはほんっとに苦労しました。
同じ事象に血を吐いている同志達の参考になれば幸いです。

IT, Java

Posted by raishin