Spring boot × postgres をHerokuへデプロイしてみる。(gradle編)

# はじめに
Herokuを使い始めて、色々とデプロイを試しているかなの忘却録です。
spring-boot(gradle) × postgresのでもアプリを作成し、Herokuへのデプロイ方法を記述しています。

基本的には色々な方が挙げているものと似通っていますが
postgresの設定ファイルをgitignoreするとherokuへpushされず少し困ったのでその解決策なども書いています。

※デモアプリのベースやHerokuの初期設定は、前の記事で上げたものを流用しています。
>[graldeのSpring BootアプリケーションをHerokuへdeployしてみる](https://qiita.com/Takeuchi713/items/01f022cc24db8150763d)


# 環境
- windows 10 Home
- java 11
- spring-boot 2.3.5
- gradle 7.1.1  (gradlew)
- heroku/7.56.1 win32-x64 node-v12.21.0
- spring jpa 2.5.3

# ソース
[https://github.com/Takeuchi713/spring-boot-gradle-heroku](https://github.com/Takeuchi713/spring-boot-gradle-heroku)

# 目次
1. [herokuの設定](#1-herokuの設定)
1. [デモアプリ作成](#2-デモアプリ作成)
1. [deploy](#3-deploy)
1. [gitignore対策](#4-gitignore対策)

#1. herokuの設定
Herokuのマイページでpostgresの設定をしていきます。


### postgresを追加
マイページへログインし、アプリのダッシュボードへ移動する。
ResoucesからHeroku Postgresをアプリへ追加していく。
![1.resouce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/a1f7febd-1d2e-fea8-3f7e-50fe6db083ab.png)
Add-onsにpostgresと入力すると選択肢が表示されるのでクリック。
![2.postgres.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/ae5cf121-2c0a-5dea-de58-eb836aaa245b.png)
追加するプランを聞かれるので、今回は無料のHobby Dev-Freeを選択。
![3.Hobby Dev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/13324328-7ed3-ce29-16f1-91ca079b5cca.png)
Submit Order Formをクリックすると、Add-onsに追加され使用可能に。
![4.Heorku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/02c27590-f80c-5b37-1a75-71547b1ed17d.png)
Add-onsのHeroku Postgresをクリックすると自分専用のページが開く。
Setting => View Credenticalsをクリックすると、URLやpasswordなどpostgresへ接続するための情報が確認出来る。
![5.postgres-setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/702eadd2-aab8-80a3-9e05-bc78499c6f17.png)


#2. デモアプリ作成
前回のアプリに単純なpostgresとの連携処理を追記していきます。

### build-gradle
postgresとspring-jpaの依存性を追加。

```gradle:build.gradle
dependencies {
	//追加
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	runtimeOnly 'org.postgresql:postgresql'
}
```
### Entity
```java:MyUser.java
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name="MyUser")
public class MyUser {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private String id;
	@Column(name = "name", nullable = false, length = 100)
	private String name;
	@Column(name = "email", unique = true, nullable = false, length = 200)
	private String email;
	@Column(name = "age", nullable = true, length = 3)
	private Integer age;
	@Column(name="gender", nullable =true , length = 1)
	private Integer gender;
}
```
### Controller
```java:UserController.java
@RestController
@RequestMapping("/api")
public class UserController {
	private final MyUserRepository repository;
	UserController(MyUserRepository repository) {
		this.repository = repository;
	}

	@GetMapping("/users")
	public ResponseEntity<List<MyUser>> getUsers() {
		//本来はService等に切り出すべき
		String email = "test@test.com";
		MyUser user = repository.findByEmail(email).orElse(new MyUser(null, "takeuchi", "test@test.com", 18, 1));
		repository.save(user);
		List<MyUser> users = repository.findAll();
		return new ResponseEntity<List<MyUser>>(users, new HttpHeaders(), HttpStatus.OK);
	}
}
```

### Heroku Postgresに接続するための設定
Heroku PostgresのSettingに記載されている内容を設定。
※{Host},{Port}などはHerokuのSettingに書かれているものに置き換えて考えてください。

```yml:application.yml
spring:
  datasource:
    url: jdbc:postgresql://{Host}:{Port}/{Database}?sslmode=require
    username: {User}
    password: {Password}
    driverClassName: org.postgresql.Driver
  jpa:
    database: POSTGRESQL
    show-sql: true #sqlをconsoleへ表示するか否か
    hibernate:
      ddl-auto: create  #起動時にEntityからテーブルを自動生成し、終了時に削除する。ちなみに、updateとすると作成のみに変更可
```

### 動作確認
```
curl http://localhost:8080/api/users
[{"id":"1","name":"takeuchi","email":"test@test.com","age":18,"gender":1}]
```

#3. deploy
特に特殊なことなく、commitしpushすると自動でdeployされる

```
git add .
git commit -m "add postgres"
git push heroku main
```
ブラウザから動作確認
![heroku-deploy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/902192bf-ab71-a7e7-2d4d-3005f80ed989.png)


#4. gitignore対策
以上で問題なくデプロイできましたが、、、
githubにソース登録しようとして、ymlをgitignoreすると
Herokuへpush時もymlが無視されてしまい、デプロイに失敗し動かず...

隠したい部分をHerokuで環境変数として設定する方法で解決しました。

### Herokuで環境変数を設定
アプリのページからSetting => Reveal Config Varsを選択し環境変数を表示する
![setting-Revea.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/d8d46248-02de-652b-ef6d-9c8028658760.png)

環境変数を追加
POSTGRES_PASS, POSTGRES_USER, POSTGRES_URLを追加
※DATABASE_URLはデフォであるので特に変更しないで大丈夫です。
![Config Vars.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295610/3baef8a8-ddc2-7e40-26e6-4538032e14da.png)

### spring-bootの設定を変更
${}で囲った部分が環境変数で置き換えられます。

```yml:application.yml
spring:
  datasource:
    url: ${POSTGRES_URL}
    username: ${POSTGRES_USER}
    password: ${POSTGRES_PASS}
    driverClassName: org.postgresql.Driver
  jpa:
    database: POSTGRESQL
    show-sql: true #sqlをconsoleへ表示するか否か
    hibernate:
      ddl-auto: create  #起動時にEntityからテーブルを自動生成し、終了時に削除する。ちなみに、updateとすると作成のみに変更可
```

### 動作確認
gitignoreからymlを外して、上と同じようにdeployする。

```
git add .
git commit -m "add postgres"
git push heroku main
```

問題なく、動いていることを確認

```
curl "https://spring-gradle-deploy.herokuapp.com/api/users"
[{"id":"1","name":"takeuchi","email":"test@test.com","age":18,"gender":1}]
```