AWS→heroku移行(SpringBoot/Gradle)

# はじめに
[GoogleCalendarAPIを用いたアプリをAWSにデプロイ](https://qiita.com/hhujk5/items/a37cb17041c3e1070ac7)していましたが、
AWSのRDS利用開始から1年が経ち有料となったのでherokuへ移行しました。
herokuへのデプロイに関する記事は色々ありますが、情報が古かったり環境が微妙に異なったりで所々詰まりました。
どなたかの一助となれば幸いです。

# 環境
- macOS Monterey 12.3.1
- Java (AdoptOpenJDK 11.0.10)
- SpringBoot 2.5.2
- gradle 7.0.2

# 以下、実際に行った手順です

## 事前準備
- herokuアカウント作成
https://jp.heroku.com から作成
- heroku CLIをインストール
homebrewでインストール
$ brew tap heroku/brew && brew install heroku
参考：https://devcenter.heroku.com/ja/articles/heroku-cli

- ブランチを切る
私はheroku向けに行った作業は分けたいと思い、
for-herokuという名前でブランチを切りました。

(コード管理はGitHubで行っている前提です)

## herokuへpushまで

### 1. build.gradleの修正
```groovy:build.gradle
修正した箇所のみ記載しております。


(元々Tomcatへのデプロイ用にwarファイル指定指定していたものを削除)
plugins {
	// id 'war' 
}

war {
	// enabled = true
	archiveName = 'TaskTime'
}

(Tomcat用の記載を修正)
dependencies {
	// providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
}

(以下追記)
defaultTasks "clean", "build"
~
```




### 2. Procfile作成
```shell:Procfile
# ポート番号は$PORTと設定してください。もしforeman(Procfileを読み込み起動してくれるもの)で設定確認する場合は、ご自身の環境のポート番号を設定してください。)
web: java -jar build/libs/TaskTime.jar --server.port=$PORT
```

### 3. system.properties作成
```system.properties
# Javaのバージョンが8でない場合は必要
java.runtime.version=11
```
参考

https://devcenter.heroku.com/ja/articles/java-support

>Heroku は現在、デフォルトで OpenJDK 8 を使用してアプリケーションを実行しています。
~
system.properties​ というファイルをアプリケーションに追加することによって Java バージョンを指定できます。


### 4. herokuへログイン
```shell
$ heroku login
```


### 5. heroku内にアプリ作成
```shell
$ heroku create 任意のアプリ名
```

### 6. gradleのbuildpackを指定
```shell
# herokuへpushした時にgradleでビルドするよう指定します。
$ heroku buildpacks:set heroku/gradle
```
参考

https://devcenter.heroku.com/ja/articles/buildpacks

>デフォルトでは、これらの buildpack は一致が検出されるまでこの順に検索され、アプリのコンパイルに使用されます。ビルドに成功した場合、検出された buildpack は今後のアプリケーションへのプッシュ用に永続的に設定されます

と記載がありますが、私はその前に色々いじってしまっていたので念のためbuildpack指定しました。

### 7. やっとherokuへpush!
```shell
# 私はmainブランチでなくfor-herokuというブランチで作業したため以下のように記載しております。
$ git push heroku for-heroku:master
```

### 8. アプリが起動できているか確認
```shell
$ heroku open
=>ブラウザでアプリのトップページが起動するはず

# ここでエラーが生じている場合は heroku logs -t でログを確認してください。
# もしDB関連のエラーが出ている場合は、次の「DB関連設定」を先に行ってください。
```

## DB関連設定
### 1. Add-onsにClearDBを追加
参考

https://trialanderror.jp/heroku-mysql-start/

### 2. DB接続用のheroku内環境変数を設定
```shell
# ClearDBを追加と同時にユーザー名やパスワードが作成されるので中身を確認
$ heroku config
=== [アプリ名] Config Vars
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true

# heroku configで確認した内容を変数に入れる
$ heroku config:add DB_NAME='[データベース名]'
$ heroku config:add DB_USERNAME='[ユーザー名]'
$ heroku config:add DB_PASSWORD='[パスワード]'
$ heroku config:add DB_HOSTNAME='[ホスト名]'
$ heroku config:add DB_PORT='3306'

```
参考

https://qiita.com/Takao_/items/aeb3570b42a6aeb5461f

(上記のようにCLIで設定できますが、herokuのdashboardからGUIで設定することもできます。そちらの方が楽かもしれません。)


### 3. 環境変数を元にファイル修正
```yml:application.yml
spring:
  datasource:
    url: jdbc:mysql://${DB_HOSTNAME}:3306/${DB_NAME}?serverTimezone=Asia/Tokyo
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}

```

## Google OAuth2.0に関する対応
###  1. application.ymlに設定している環境変数をherokuにも設定
```shell
$ heroku config:add CLIENT_ID='[自分のアプリのclient-id]'
$ heroku config:add CLIENT_SECRET='[自分のアプリのclient-secret]'
```
### 2. 各種URL変更
- application.yml内のredirect-uriを変更
- Google Cloud Platformにて承認済みドメインに[アプリ名.herokuapp.com]を追加
- Google Cloud Platformにて承認済みのリダイレクトURIに[https://アプリ名.herokuapp.com/login/oauth2/code/google]を追加


## その他、詰まったところなど

### 1. returnするhtmlファイルの先頭からスラッシュを削除
ご参考

https://qiita.com/dumbbell/items/e9734ee15d4b8cf60793


### 2. 文字化け問題

#### まず以下の記事を参考に設定を確認しましたが、、、
https://qiita.com/kakudaisuke/items/73aa165bc0f0db522f4f

私の環境では解決しませんでした。


herokuのMySQLにログインし、
```shell
$ mysql -u [ユーザー名] -p -h [ホスト名] [データベース名]
```
DBの文字コード状況を確認。
character_set_server以外はutf8で設定できておりました。
```shell
$ mysql> show variables like 'character%';
+--------------------------+------------------------------+
| Variable_name            | Value                        |
+--------------------------+------------------------------+
| character_set_client     | utf8                         |
| character_set_connection | utf8                         |
| character_set_database   | utf8                         |
| character_set_filesystem | binary                       |
| character_set_results    | utf8                         |
| character_set_server     | latin1                       |
| character_set_system     | utf8                         |
| character_sets_dir       | /usr/share/mysql56/charsets/ |
+--------------------------+------------------------------+
```

#### そして以下の記事を参考に解消できました。
https://learning-collection.com/heroku-%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91%E3%81%AE%E5%AF%BE%E5%87%A6%E6%B3%95/

heroku configのCLEARDB_DATABASE_URLの末尾に以下を追記しました。
```
characterEncoding=UTF-8&characterSetResults=UTF-8

(記述例)
mysql://ユーザーID:パスワード@ホスト名/データベース?reconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
```