超初心者がDB接続するSpringBootアプリをAWSにデプロイする【後編】

# はじめに
駆け出しJavaエンジニアでインフラの知識もデプロイ経験もほぼ無い筆者が、Springで作成したアプリケーションをAWSにデプロイすることに成功した手順を、遭遇したエラーも交えながら記していきます。
長いので２部構成になっています。本記事は**後編**です。

**【前編】AWS環境の構築**
* VPCの構築
* EC2インスタンスの設置
* RDSの設置
前編はこちら↓

https://qiita.com/sai-i/items/00fc6e27235f94fcd0fa

### 【後編】動作環境の構築とデプロイ
* ミドルウェアのインストール
* Springアプリケーションのデプロイ

※この記事は2023年2月8日に書かれたものです。
AWSは更新が激しいようなので使用している画像のマネージメントコンソール等のUIが異なる可能性があります。ご了承ください。

# 前提
* AWSのアカウント登録
* AWS環境の構築
* Springアプリケーションの作成
* インフラの基礎知識

インフラの知識と環境構築方法については下記のUdemy教材で学習しました。
手順だけではなくインフラの基礎知識についても学習することができます。

https://www.udemy.com/course/aws-and-infra/

# 環境
* PCのOS：macOS Big Sur 11.2
* SpringBoot：2.7.0
* Java：OpenJDK 11.0.16.1
* DB：PostgreSQL 10.21

# 全体像
本記事では下図の状態を目指して環境を構築します。
（今回はドメインの取得は行いません。）
![AWS図2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3127048/4f39b320-b5ff-26ca-9e56-f1d27d4e7389.png)

# ミドルウェアのインストール
### 1.SSHでサーバーにログイン
**SSHとは**サーバーと自分のPCをセキュアに繋ぐサービスのことです。
SSHでサーバーにログインすると、自分のPCから離れたサーバーに入りWebサーバーを操作できるようになります。

まず、秘密鍵の読み書き権限を所有者のみに設定します。
これを行わないとSSHでログインができません。

秘密鍵とは、対になる公開鍵で暗号化された通信を復号するために使うキーのことです。
前編でEC2インスタンスを作成した際にダウンロードされたキーペアがここで必要になります。
```
# 権限の変更
chmod 600 秘密鍵(キーペア)のファイルパス
```

次に、sshコマンドを使ってサーバーにログインします。
```
# SSHでEC2にログイン
ssh -i 秘密鍵(キーペア)のファイルパス ec2-user@パブリックIPアドレス
```
※パブリックIPアドレスの調べ方
EC2 → インスタンス → 該当のインスタンスを選択 → 詳細タブ → パブリックIPv4アドレス
![スクリーンショット 2023-02-08 15.59.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3127048/7cddb32b-0486-1d10-abe5-c82f249c6868.png)


### 2.Apacheのインストール
以下のコマンドを入力してApacheをインストールします。
httpd：Apacheを構成する実行ファイル
```
# apacheのインストール
sudo yum -y install httpd
# apacheの起動
sudo systemctl start httpd.service
# apacheの起動確認（activeと表示されればOK）  
sudo systemctl status httpd.service
# サーバー接続時に自動でapacheが起動するよう設定
sudo systemctl enable httpd.service
```
パブリックIPアドレスをブラウザのURLに貼り付けて、ApacheのTest Pageが表示されれば正常です。

# ここでエラーが
**ApacheのTest Pageが表示されませんでした。**
読み込みマークがぐるぐるし続けて、しばらくするとタイムアウトしてしまう。

原因はEC2インスタンス設置時に作成したセキュリティグループのインバウンドルールに、インターネットからのアクセスを許可するルールを追加していないことでした。

EC2 → セキュリティグループ → 該当のセキュリティグループの選択 → インバウンドルール → インバウンドのルールを編集　から、ルールに「タイプ：HTTP、ソース：Anywhere IPv4(0.0.0.0/0)」を追加したところ、無事テストページが表示されました。
![スクリーンショット 2023-02-08 16.45.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3127048/9aea8322-ac2b-460b-8cb7-e7dfa7b285f3.png)

# ミドルウェアのインストール（続き）
### 3.Tomcatのインストール
以下のコマンドを入力してTomcatをインストールします。
```
sudo yum install tomcat
# ブラウザで確認するためにadmin-webappsをインストールする。
sudo yum install tomcat-webapps admin-webapps
# Tomcatの起動
sudo systemctl start tomcat
```

今回はインバウンドルールも忘れずに追加します。
Apacheと同様の手順で、「タイプ：カスタムTCP、ポート範囲：8080、ソース：Anywhere IPv4(0.0.0.0/0)」をルールに加えます。
![スクリーンショット 2023-02-08 17.18.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3127048/f9121ef3-e284-bb9b-922a-f2e5f0f62b45.png)
「パブリックIPアドレス:8080」をブラウザのURLに打ち込み、Tomcatのウェルカムページが表示されれば正常です。

### 4.PostgreSQLのインストール
以下のコマンドを入力してPostgreSQLをインストールします。
```
# 利用可能なpostgresqlを表示
$ amazon-linux-extras list | grep postgre
 6  postgresql10             available    [ =10  =stable ]
 41  postgresql11             available    [ =11  =stable ]
 58  postgresql12             available    [ =stable ]
 59  postgresql13             available    [ =stable ]
 63  postgresql14             available    [ =stable ]
```
表示されたものの中からバージョンを選択してインストールします。
```
　# postgresqlインストール
amazon-linux-extras install postgresqlバージョン
# postgresqlに接続
psql -h RDSのエンドポイント -U postgresqlのユーザー名
```
接続ができたら、必要なDBやテーブルの作成をしましょう。

※RDSのエンドポイントの調べ方
RDS → データベース → 該当のデータベースのDB識別子を押下 → 接続とセキュリティ → エンドポイント
![スクリーンショット 2023-02-08 17.51.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3127048/293b6a73-6db6-e2ce-83d2-09d7488a5d0c.png)


# Springアプリケーションのデプロイ
### 1.設定の変更
デプロイするSpringBootアプリケーションのapplication.yml(application.propaties)を編集します。
```yml:application.yml
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://エンドポイント:5432/DB名
username: ユーザー名
password: パスワード
```

### 2.jarファイルの作成
STS上で、プロジェクトを右クリック → Run As → Maven install でアプリケーションをjarファイル化します。
作成されたjarファイルはプロジェクト直下のtargetフォルダに格納されます。

### 3.Tomcatへの配置
作成したjarファイルをscpコマンドを利用してtomcatのwebappsフォルダに配置します。
scpコマンドは、ssh接続を使用してローカルコンピュータとリモートコンピュータ間またはリモートコンピュータ間のファイルのコピーを行うコマンドです。
```
# targerフォルダへ移動
cd　　targetへのパス
# jarファイルをwebappsフォルダにコピー
sudo scp -i 秘密鍵のファイルパス jarファイル名 ec2-user@パブリックIPアドレス:/usr/share/tomcat/webapps
```

# ここで再びエラーが

```
scp: /usr/share/tomcat/webapps/jarファイル: Permission denied
```
アクセス拒否をされてしまいました。
どうやらwebappsファイルを編集する権限がないようです。

以下のようにファイルのコピーを行った後に管理者権限でwebappsフォルダまで移動させる方法だと成功しました。
```
# jarファイルをEC2上にコピー
sudo scp -i 秘密鍵のファイルパス jarファイル名 ec2-user@パブリックIPアドレス:
# SSHでEC2にログイン
ssh -i 秘密鍵(キーペア)のファイルパス ec2-user@パブリックIPアドレス
# 管理者権限でwebappsフォルダに移動させる
sudo mv jarファイル /usr/share/tomcat/webapps/
```
この方法の場合は、この後アプリケーションの実行を行う際も管理者権限でコマンドを実行する必要があります。

また、あまり良くはないですが、EC2に接続してwebappsファイルの権限を一時的に777(全てのユーザーに権限を与える)にすることでも実行可能でした。

```
# SSHでEC2にログイン
ssh -i 秘密鍵(キーペア)のファイルパス ec2-user@パブリックIPアドレス
# 全てのユーザーに権限を与える
sudo chmod 777 /usr/share/tomcat/webapps
# ローカルでsudoコマンドを使ってコピー
sudo scp -i 秘密鍵のファイルパス jarファイル名 ec2-user@パブリックIPアドレス:/usr/share/tomcat/webapps
```

# Springアプリケーションのデプロイ(続き)
### 4.実行
以下のコマンドを打つことで、アプリケーションが起動します。
```
java -jar ファイル名
```
しかし、、
# またエラー
```
***************************
APPLICATION FAILED TO START
***************************

Description:

Web server failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
```
8080ポートが使用されているようです。

原因は、Tomcatが起動していて既に8080ポートを使用していたためでした。
下記のコマンドを入力しTomcatを停止させます。

```
sudo systemctl stop tomcat
```
そしてもう一度実行のコマンドを入力すると、、、アプリケーションが正常に起動しました！！

ブラウザにURLを打ち込み、Webサイトが表示されたらデプロイ完了です。
お疲れ様でした！

# 終わりに
【後編】動作環境の構築とデプロイ は以上です。
理解や環境構築の一助となれば幸いです。

前編ではAWS環境の構築の手順について記しています。

https://qiita.com/sai-i/items/00fc6e27235f94fcd0fa
# 参考

https://www.udemy.com/course/aws-and-infra/

https://midorigame-jo.com/aws-deploy2/