SpringBootで作成したアプリケーションをHerokuへデプロイ(公開)②


SpringBootで作成したアプリケーションをHerokuへデプロイ(公開)①の続きです。

④Heroku上にアプリを作成

下記のコマンドでHeroku上にアプリを作ります。

$ heroku create <アプリの名前>

アプリの名前を付けずに実行すると、自動的に命名されます。
アプリ名を「myapp」にしたい場合は「heroku create myapp」ですね。

コマンドを使わずに、Herokuのサイト上でも作成できます。

・サイト右上の「new」から「Create new app」を選択

・アプリ名を入力し、「Create app」を押す
regionは現在アメリカか、ヨーロッパのどちらかしか選択できません。

⑤PostgresをAdd-on、データを追加

HerokuはH2をサポートしておらず、DB管理システムとしてH2を利用している場合、アプリケーションは正常に動作しません。
H2の代わりのPostgresを利用します。Herokuの公式サイトには、HerokuがPostgresを長年運用し、多くのユーザーとのやりとりによって培ったノウハウがあるとのことでHerokuとPostgresの相性の良さが保証されています。

まず④で作成したアプリケーションのページを開き、「Resources」のタブにある「Add-ons」で「Heroku Postgres」を検索します。

「Heroku Postgres」を選択すると下図のようなポップアップが開くので「Submit Order Form」を押します。

ターミナルでPostgresのコマンド入力しデータベースを操作するので、OSにpostgresSQLをインストールします。

$ brew install postgresql

bash.profileを編集してパスも通してください。

bash.profile
export PATH=/usr/local/Cellar/postgresql@12/12.4_1/bin:$PATH

下記のコマンドを入力し、DBの接続情報を取得します。

$ heroku pg:credentials:url --app [APP-NAME]

Connection information for default credential.
Connection info string:
   "dbname=hogehogehoge host=hogehoge123.amazonaws.com port=5432 user=mrhoge password=hogehoge1964 sslmode=require"
Connection URL:
   postgres://USER-NAME:PASS@HOST:5432/DBNAME

続いて、データベースに接続します。

$ heroku pg:psql -a [APP-NAME]
--> Connecting to postgresql-XXXXXX-XXXXXX
psql (10.6)
SSL 接続 (プロトコル: TLSv1.2、暗号化方式: ECDHE-RSA-AES256-GCM-SHA384、ビット長: 256、圧縮: オフ)
"help" でヘルプを表示します。
[APP-NAME]::DATABASE=>

接続したデータベースに、アプリケーションで使用するテーブルを作成します。

例:

[APP-NAME]::DATABASE=> CREATE TABLE IF NOT EXISTS food (
  foodID INT PRIMARY KEY,
  name VARCHAR(100),
  price VARCHAR(500),
  description VARCHAR(3000)
);

CREATE TABLE IF NOT EXISTS userData (
    userId VARCHAR(50) PRIMARY KEY,
    mailAddress VARCHAR(100),
    password VARCHAR(100),
    role VARCHAR(50)
);

ちなみにpostgresqlの制約でテーブル名を「user」とすることはできません。
別の名前にしましょう。

作成したテーブルにデータを追加していきます。
例:

[APP-NAME]::DATABASE=> INSERT INTO food(foodID, name, price, description) VALUES
('1', 'ロールケーキ', '1000円 ', 'ロールケーキ専門店で、手作りしている為、1日80本限定販売です。'),
('2', 'イチゴケーキ', '900円 ', 'イチゴケーキ専門店で、手作りしている為、1日80本限定販売です。'),
('3', 'チョコケーキ3', '1000円 ', 'チョコケーキ専門店で、手作りしている為、1日80本限定販売です。'),
('4', 'チーズケーキ4', '800円 ', 'チーズケーキ専門店で、手作りしている為、1日80本限定販売です。'),
('5', '抹茶ケーキ5', '1200円 ', '抹茶ケーキ専門店で、手作りしている為、1日80本限定販売です。');

複数のレコードを追加するときは、INSERTのSQL文は上記の書き方をお勧めします!
下のSQL文で実行したら、insertできませんでした・・・
例:

INSERT INTO food(foodID, name, price, description) VALUES
('1', 'ロールケーキ', '1000円 ', 'ロールケーキ専門店で、手作りしている為、1日80本限定販売です。');
INSERT INTO food(foodID, name, price, description) VALUES
('2', 'イチゴケーキ', '900円 ', 'イチゴケーキ専門店で、手作りしている為、1日80本限定販売です。');
INSERT INTO food(foodID, name, price, description) VALUES
('3', 'チョコケーキ3', '1000円 ', 'チョコケーキ専門店で、手作りしている為、1日80本限定販売です。');
INSERT INTO food(foodID, name, price, description) VALUES
('4', 'チーズケーキ4', '800円 ', 'チーズケーキ専門店で、手作りしている為、1日80本限定販売です。');
INSERT INTO food(foodID, name, price, description) VALUES
('5', '抹茶ケーキ5', '1200円 ', '抹茶ケーキ専門店で、手作りしている為、1日80本限定販売です。');

データの追加が成功すると追加したレコードの行数が表示されます。
例:5行のレコードを追加

INSERT 0 5

下のコマンドでデータベースとの接続を切ります。

[APP-NAME]::DATABASE=> \q 

参考
postgresSQLのインストールについて:https://qiita.com/yorokobi_kannsya/items/f77d074e382a88dae971
接続情報の取得とデータベースへの接続について:https://sysrigar.com/2019/01/20/heroku-postgres%E3%82%92%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E7%92%B0%E5%A2%83%E3%81%8B%E3%82%89%E6%89%8B%E5%8B%95%E3%81%A7%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4/
「heroku pg:psql -a [appname]」が効かない時の対処法について:https://qiita.com/Puerto/items/5b886d0ed202761c4cc1

⑥pom.xmlに「postgresql」を追加

pom.xmlに「postgresql」を追加します。

pom.xml
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

⑦Postgres関連の環境変数を設定

Herokuのアプリケーションのページを開き、「Heroku Postgres」をクリックします。

「Settings」の「View Credentials」をクリックします。

Herokuのpostgresqlの設定値が一覧で表示されるので、丸々メモなどにコピペしておきます。
画像では「AAA」「BBB」としていますが、公開すべき情報ではないのでテキストを後から貼り付けています。

Herokuのアプリケーションのページに戻り、「Settings」のタブにある「Config Vars」で先ほどの確認した設定値を環境変数としてセットします。

「KEY」に変数名、「VALUE」に値を入力して「Add」をクリックすれば環境変数を追加できます。
変数名は「View Credentials」で表示されているものとは異なった名前にされる方が多いです。

「View Credentials」から「Host」「Database」「User」「Password」の値を環境変数に追加してください。

次に使用しているIDEに環境変数を追加します。
筆者はEclipseを使用しているので、Eclipseでのやり方を紹介します。

プロジェクトを右クリック「実行」、「実行の構成」を開きます。

「Maven ビルド」で作業中のプロジェクト名と同名のものを開きます。(例 プロジェクト名「Snitch3」)
名前に先ほど「Config Vars」で設定したのと同名のものを入力し、値を入力し「OK」を押します。

下図は環境変数の追加が完了した状態です。

必ず適用を最後に押してください!
筆者は適用をし忘れ、デプロイができないといった事象に1日悩みました。
正常に適用されたか心配な場合は、再度「環境」タブを開くといいでしょう。

最後に「application.properties」を編集します。
ファイルの内容が大きく変わるので、ローカル環境で稼働させていた時に使用していたファイルの内容は別名で保存するなどしてください。

下記の内容をそのまま貼り付けてください。
記述されている内容を見ると、「View Credentials」やEclipseで設定した変数名が記述されています。
ここに先ほど設定した値が当てはめられ、正常にデータベースのやりとりが行われます。
これによりパスワードなど情報を非公開にしつつ、機能させることができます。

application.properties
spring.datasource.url=jdbc:postgresql://${host}/${database}?sslmode=require
spring.datasource.username=${POSTGRES_USER}
spring.datasource.password=${POSTGRES_PASS}
logging.level.jdbc=OFF
logging.level.jdbc.sqltiming=DEBUG

⑧mavenビルドをしてjarファイルを作成

Eclipseを開き、プロジェクトを右クリック。「実行」の中にある「8 mavenビルド」を実行します。

正常に動作すると、コンソール上に「BUILD SUCCESS」と表示されます。

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ Snitch ---
[INFO] Building jar: /Applications/Eclipse_2020-06.app/Contents/workspace/Snitch3/target/Snitch-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (repackage) @ Snitch ---
[INFO] Replacing main artifact with repackaged archive
[INFO] 
[INFO] --- maven-dependency-plugin:3.1.2:copy (default) @ Snitch ---
[INFO] Configured Artifact: com.heroku:webapp-runner:9.0.30.0:jar
[INFO] com.heroku:webapp-runner:9.0.30.0:jar already exists in /Applications/Eclipse_2020-06.app/Contents/workspace/Snitch3/target/dependency
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  19.166 s
[INFO] Finished at: 2020-10-31T12:04:02+09:00
[INFO] ------------------------------------------------------------------------

ルートディレクトリ直下の「target」フォルダを確認すると、前回の記事で説明した「任意の文字列-0.0.1-SNAPSHOT.jar」が作成されています。

例:アプリ名「Snitch」

⑨Herokuへデプロイ

「target」配下の「任意の文字列-0.0.1-SNAPSHOT.jar」をデプロイします。

ターミナルでルートディレクトリをカレントディレクトリに設定し、「git init」でgitのリポジトリを新規作成します。

$ cd /Applications/Eclipse_2020-06.app/Contents/workspace/Snitch3
$ git init
Reinitialized existing Git repository in /Applications/Ecl・・・

アプリケーションを指定してローカルのリポジトリと紐づけます。
続いて「heroku deploy:jar target/<任意の文字列>-0.0.1-SNAPSHOT.jar --app アプリ名」でデプロイします。
例:アプリ名「Snitch1」

$heroku git:remote -a snitch1
$heroku deploy:jar target/Snitch-0.0.1-SNAPSHOT.jar --app snitch1

少々時間がかかりますが、成功するとコンソールに下記のようになります。

Uploading Snitch-0.0.1-SNAPSHOT.jar
-----> Packaging application...
       - app: snitch1
       - including: target/Snitch-0.0.1-SNAPSHOT.jar
-----> Creating build...
       - file: slug.tgz
       - size: 47MB
-----> Uploading build...
       - success
-----> Deploying...
remote: 
remote: -----> heroku-deploy app detected
remote: -----> Installing JDK 14... done
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 114.1M
remote: -----> Launching...
remote:        Released v15
remote:        https://snitch1.herokuapp.com/ deployed to Heroku
remote: 
-----> Done

コマンド「heroku open -a アプリ名」でアプリを開いてみます。

$heroku open -a snitch1

アプリケーションが正常に表示されました。

ここから各機能が正常に動くか検証されたい場合は「View logs」でログを確認できますので、動作に不備があった場合はここを確認してみてください。

以上です!
結構長文になってしまいましたが、参考になれば幸いです。

参考:
https://www.bedroomcomputing.com/2019/11/2019-1101-heroku-springboot-postgres/#%E6%B3%A8%E6%84%8F
https://raishin.xyz/springboot-heroku-deploy/
https://codezine.jp/article/detail/8187?p=3
https://poppingcarp.com/heroku_postgres/
https://sun-blog.site/spring%E3%81%A7%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E6%AF%8E%E3%81%AB%E7%95%B0%E3%81%AA%E3%82%8Bdb%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E3%80%82/