Springで作成したWebサーバをEC2に配置してローカルからアクセスするまで


## はじめに

近々API関連の知識が必要になりそうだったので、[こちらの記事](https://zenn.dev/msksgm/books/implementing-server-side-kotlin-development/viewer/chapter-02-03-spring-intro-crud)を参考にAPIサーバを作りました。  

最近の環境的にはAWSを使うのが一般的なようなので、とりあえずAWS上に配置して使えるようにしようと思い、試行錯誤した手順をまとめておきます。

## 私のスペック

- REST APIの知識は少しある
- EC2は構築済みの環境なら触ったことがある
- インフラ関連の知識は断片的にあるが、体系的には身についていない
- Linuxについては十分理解している
- C言語が好き

## やりたいこと

[この本](https://zenn.dev/msksgm/books/implementing-server-side-kotlin-development/viewer/chapter-02-03-spring-intro-crud)の2.3章を元に作ったWeb APIサーバをEC2上に構築します。

目標は、以下のようなGETリクエストをローカルのコマンドプロンプトからAWS上のサーバに送信し、意図した結果を取得することです。

```bash
> curl --location --request GET http://<public-address>:8080/customers
{"customers":[{"id":1,"firstName":"Alice","lastName":"Sample1"},{"id":2,"firstName":"Bob","lastName":"Sample2"}]}
```

## 手順

### 1. EC2インスタンスの作成〜SSH接続まで

以下の記事を参考に進めたらできました。  
[https://qiita.com/takuma-jpn/items/b2c04b7a271a4472a900](https://qiita.com/takuma-jpn/items/b2c04b7a271a4472a900)

---

### 2. EC2の環境構築

今回作成したWebサーバはSpringで構築しました。  
ビルドするとjarファイルが生成されるので、これを動作させられる環境を用意すればWebサーバとして機能するはずです。必要なパッケージをインストールしていきます。

#### 2.1 Javaのインストール

```bash
sudo yum install java-21-amazon-corretto
```

`~/.bashrc`に環境変数を追記します。

```bash
export JAVA_HOME=/etc/alternatives/java-21-amazon-corretto
export PATH=$JAVA_HOME/bin:$PATH
```

#### 2.2 Gradleのインストール

```bash
wget https://services.gradle.org/distributions/gradle-8.11.1-bin.zip
sudo mkdir /opt/gradle
sudo unzip -d /opt/gradle/ gradle-8.11.1-bin.zip
```

#### 2.3 Dockerのインストール

```bash
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker.x86_64
```

#### 2.4 Docker Composeのインストール

```bash
# ダウンロードとインストール
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 起動ユーザの追加
sudo usermod -aG docker ec2-user

# Dockerの起動
sudo systemctl start docker

# docker-compose.yamlのあるパスで実行
docker-compose up -d 
```

---

### 3. アプリケーション設定

外部からサーバにアクセスできるようにするための設定を行います。

#### 3.1 `application.properties`への追記

以下の設定を追記します。

```properties
server.port=8080
server.address=0.0.0.0
```

#### 3.2 ポートの開放 (Linux側)

```bash
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
sudo iptables -L -n # 確認
```

---

### 4. インスタンス設定

#### 4.1 セキュリティグループの設定

EC2インスタンスに関連付けられたセキュリティグループの設定を確認し、必要な設定を追加します。

1. AWS Management Consoleにログインします。
2. 「EC2サービス」→「対象のインスタンス」→「セキュリティグループ」→「インバウンドルール」の順に進みます。
3. 以下の設定を追記します。

- **タイプ**: カスタムTCP
- **プロトコル**: TCP
- **ポート範囲**: 8080（Webサーバが使用するポート）
- **ソース**: 0.0.0.0/0（全世界からアクセス可能）または必要なIP範囲

---

### 5. 実行

ここまでの操作で作成したSpringプロジェクトが動作するはずです。作成したjarファイルをEC2環境にコピーし、以下のコマンドで実行します。

```bash
java -jar hogehoge.jar
```

AWSのインスタンス詳細にパブリックIPv4アドレスが記載されているので、そのアドレスに対してローカルのコマンドプロンプトからGETリクエストを送信します。

```bash
F:\work\aws>curl --location --request GET http://<public-address>:8080/customers
{"customers":[{"id":1,"firstName":"Alice","lastName":"Sample1"},{"id":2,"firstName":"Bob","lastName":"Sample2"}]}
```

無事に目的のレスポンスを取得できました！

---

## おわりに

インフラやWeb系の知識がほとんどない状態からここまで実現しようとすると、5年前の自分なら2週間くらいかかったと思いますが、今ではChatGPTがちょっとした詰みポイントを全て瞬殺してくれます
実際にかかった時間はAPIサーバの写経も含めて半日程度でした
初学者にとても優しい時代になったと感じると同時に、これからのエンジニアに求められる技術水準の高さに震える日々です。
ChatGPTに分析思考力で勝てなさそうなITエンジニアの自分が、世界に提供できる価値ってなんなんでしょう