9
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SpringBoot/React/MySQLの簡単なアプリをAWS EC2にデプロイする

Last updated at Posted at 2021-07-10

ゴール

  • 開発環境でアプリは作るけど、どうやって本番環境に公開していいのかわからん!

    開発環境でアプリは作れるし、泥臭いけどアプリを公開することができる!
    に変えることができる!

  • よくあるバックエンド(Java SpringBoot)・フロントエンド(React)・DB(MySQL)の
    構成で作成した簡単なアプリを公開し、自宅のPCからアクセスできるようになる

この記事でやること

  • SpringBootを使ったJavaアプリケーションをEC2上に立ち上げる
  • JavaアプリケーションからAmazonRDS(MySQL)に接続する
  • ReactアプリケーションをEC2上に立ち上げる

この記事でやらないこと

  • アプリケーションのソースコードの解説

手順(かかる時間)

  1. 全体構成図(読むだけ。5分)
  2. ローカルで動くSpringBoot/React/MySQLのサンプルアプリの作成
  3. VPCの構築(20分程度)
  4. RDSインスタンスの作成(5分)
  5. EC2インスタンスの作成(5分)
  6. EC2インスタンス上でアプリを起動(10分)
  7. 動作確認

計:1時間~程度

1. 全体構成図

ざっくり以下の構成です!

  • 東京リージョン内の2つのアベイラビリティーゾーンにWebサーバ、APサーバ、DBサーバを構成
  • EC2をWebサーバ、APサーバとして、RDSをDBサーバとして利用しています
    全体構成図.png

2. ローカルで動くSpringBoot/React/MySQLのサンプルアプリの作成

サンプルアプリのソースコード

  • SpringBootについて
    • サンプルソースコード: こちら
    • application.properties を src/main/resources 配下に配置
src/main/resource/application.properties
spring.datasource.url=jdbc:mysql://${MySQLのエンドポイント}:3306/{DBName}?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=${ルートユーザ}
spring.datasource.password=${ルートユーザのパスワード}
server.servlet.context-path=/react-sample-app/
  • Reactについて

  • MySQLについて

    • Dockerで構築しました
    • データを用意するのが面倒だったので以下を利用しています
      MySQL:world_database
  • その他

    • Nginxを利用してプロキシパスを設定しています
nginx.conf
server {
    listen       80;
    server_name  localhost;

    // Reactへのアクセス
    location / {
        proxy_pass http://localhost:3000;
    }

    // SpringBootへのアクセス
    location /react-sample-app {
        proxy_pass http://localhost:8080/react-sample-app;
    }
}

動作確認

  • http:localhost/ にアクセス
  • 以下のような画面が表示され、国コード(完全一致)を入力すると、それに伴うデータが表示されればOK!
    image.png

3. VPCの構築

  • 開発環境で動作したらいよいよ公開準備です
  • VPC内に3つのサブネットを構築します
Subnet AZ IPv4 CIDRブロック 用途
PublicSubnet1 ap-northeast-1a 10.0.0.0/24 Web/APサーバ用
PrivateSubnet1 ap-northeast-1a 10.0.1.0/24 DBサーバ用
PrivateSubnet2 ap-northeast-1c 10.0.2.0/24 DBサーバ用(冗長構成)
  • パブリックサブネット :Internet Gatewayに接続しているサブネット(インターネットにつながる)
  • プライベートサブネット:Internet Gatewayに接続していないサブネット(インターネットにつながらない)

VPC構成図.png

手を動かしてVPC構成する

具体的な手順は以下

VPCの作成

  1. VPCホーム にアクセス
  2. VPCの作成 から以下の画像のように入力(名前タグは適当に、今回IPv4CIDRブロックは 10.0.0.0/21 に)
  3. VPCを作成
    VPCの作成.png

サブネットの作成

  1. 左ペインからサブネットを選択 -> サブネットの作成
  2. 画像のように入力 -> サブネットを作成
    (3つとも同じ要領で作成)
    サブネットの作成.png

Internet Gatewayの作成

  1. 左ペインからインターネットゲートウェイを選択 -> インターネットゲートウェイの作成
  2. 名前をつけて -> インターネットゲートウェイの作成

ルートテーブルの作成

  • ルートテーブル:VPC内のルーターにおいて、ネットワーク通信の送信先を制御する(例:通信をネットワークに向ける)
    引用元:公式ドキュメント
  1. パブリックサブネット用のルートテーブルの作成
    1. PublicSubnet1 を選択 -> 詳細画面の下ペイン「ルート」を表示
      (このままではインターネットにつながっていないので、通信をInternetGatewayに向ける)
    2. ルートを編集 -> ルートを追加
    3. 送信先 0.0.0.0/0, ターゲット インターネットゲートウェイ -> 変更を保存
    4. ルートテーブル詳細画面の「サブネットの関連付け」 -> PublicSubnet1を紐付ける
  2. プライベートサブネット用のルートテーブルの作成
    (VPCのメインルートテーブルはパブリック用で利用したので、新たにイチから作成する)
    1. 左ペインからルートテーブルを選択 -> 名前をつける、VPCを選択 -> ルートテーブルを作成
    2. 作成したルートテーブルを選択 -> 詳細画面下の「ルート」表示
    3. 通信がインターネットゲートウェイに向いていないことを確認
    4. サブネットの関連付けからPrivateSubnet1,2を紐付ける
ルートテーブル 明示的なサブネットの関連付け
パブリックサブネット用 PublicSubnet1
プライベートサブネット用 PrivateSubnet1, PrivateSubnet2

以下の図のような構成まで作成完了
ルートテーブルの作成.png

セキュリティグループの作成

  1. Web/APサーバインスタンス用のセキュリティグループの作成(アウトバウンドはとりあえずデフォルトでOK)
    インバウンドルール_WEBAP.png

  2. DBサーバインスタンス用のセキュリティグループの作成(アウトバウンドはとりあえずデフォルトでOK)
    インバウンドルール_DB.png

ようやく終わり。ここまでで以下の構成のように仕上がっている
VPC構成図.png

4. RDSインスタンスの作成

  • application.propertiesもパッケージする都合上、エンドポイント・ルートユーザ周りが必要
  • そのため、先にRDSインスタンスを作成していきます
  • 概略は以下
項目
DBエンジン MySQL Community
VPC VPCの構築で作成したもの
サブネットグループ 新たに作成(PrivteSubnet1, PrivateSubnet2をグルーピング)
セキュリティグループ VPCの構築で作成したDBサーバ用のセキュリティグループ
インスタンスクラス db.t2.micro

手を動かしてRDSインスタンスを作成する

image.png

具体的な手順は以下
  1. Amazon RDSにアクセス
  2. 左ペインから サブネットグループ を選択 -> VPCの構築で作成した PrivateSubnet1 PrivateSubnet2 を選択
    ※RDSインスタンスの作成にはサブネットグループが必須です
  3. 左ペインから データベース を選択 -> データベースの作成
  4. DBエンジンの選択:(今回は)MySQL
    image.png
  5. テンプレート 開発/テスト, 無料利用枠 どちらでもOKです
  6. 設定 DBインスタンス識別子: なんでもOK, マスタユーザー名/マスターパスワードを指定します
    image.png
  7. DBインスタンスクラス 今回は db.t2.micro を選択
    image.png
  8. ストレージ はデフォルトでOK
  9. 可用性と耐久性 今回は スタンバイインスタンスを作成する で試していますが、どちらでもOK
    image.png
  10. 接続 以下の画像のように、今まで構築してきたものを選択
    image.png
  11. 概算月間コスト を確認 -> データベースの作成(金額が気になるようなら「無料利用枠」でOK)

5. EC2インスタンスの作成(5分)

  • アプリをデプロイするためのEC2インスタンスを作成します × 2(Webサーバー・APサーバー)
  • 概略は以下
ステップ 項目
AMIの選択 AMI Amazon Linux 2
インスタンスタイプの選択 インスタンスタイプ t2.micro
インスタンスの設定 ネットワーク 作成したVPC
(同上) サブネット PublicSubnet1
(同上) 自動割り当てパブリックIP 有効
ストレージの追加 - - (初期設定でOK)
タグの追加 Name WebServer, APServer
セキュリティグループの設定 セキュリティグループ 作成したWeb・APサーバ用のセキュリティグループ

手を動かしてEC2インスタンスを作成する

image.png

具体的な手順は以下
  1. EC2へアクセス
  2. インスタンスを起動
  3. Amazon マシンイメージ(AMI): Amazon Linux 2
  4. インスタンスタイプの選択: t2.micro
    image.png
    image.png
  5. ストレージの追加: 初期設定でOK
  6. タグの設定: それぞれ「Name: WebServer, APServer」
  7. セキュリティグループ: 作成したWeb・APサーバ用のセキュリティグループ
  8. key-pair のダウンロード
  9. 確認と作成(作成完了まで待ち)
  10. ステータスチェック: 2/2 のチェックに合格しました で作成完了
    image.png

6. EC2インスタンス上でアプリを起動

MySQLにデータをサンプルデータ投入

# コピーする
$ scp -i <key_pair> <world.sqlをダウンロードしたパス>/world.sql ec2-user@<WebサーバのPublicIP>:~/<お好きなところへ>
  • RDSインスタンスには直接SSH接続できないので、Webサーバを経由する
# WebサーバにSSH接続
$ ssh -i <key_pair> ec2-user@<WebサーバのPublicIP>

# MySQL のインストール
$ sudo yum install -y mysql

# RDSインスタンスに接続
$ mysql -u <マスターユーザー> -h <RDSインスタンスのエンドポイント> -p
password: <マスターユーザーのパスワード>
  • データ投入
> SOURCE ~/world.sql

Reactアプリケーションをデプロイ

  • 以下の記事を参考にデプロイします

  • アプリのビルド・起動は以下を実行(productionモードで起動するため。リソースの読み込み方法が異なります)
# yarn のインストール
$ npm -g install yarn

# アプリケーションのビルド
$ yarn build

# アプリケーションの立ち上げ
$ yarn global add serve
$ serve -s build
  • Nginxの設定
/etc/nginx/nginx.conf
server {
    # omit
    # ポート5000で起動するため
    location / {
            proxy_pass http://localhost:5000;
    }

    # APサーバに向ける。PublicIPでもいいが、PrivateIPを指定
    location /react-sample-app/ {
            proxy_pass http://{APサーバーのPrivateIP}:8080/react-sample-app/;
    }
  • Nginxの再起動
$ sudo systemctl restart nginx.service

SpringBootアプリケーションをデプロイ

  • RDSのエンドポイント/ユーザ/パスワードをapplication.properties に記載します

  • アプリケーションのビルド

// ビルドして実行可能Jarにパッケージング
$ grade buildJar
  • JarをEC2にコピー
$ scp -i <key-pair> <spring-sample-0.0.1-SNAPSHOT.jarのパス> ec2-user@<APサーバのPublicIP>:~/<お好きなところへ>
  • EC2にJavaをインストール
$ sudo yum install java-11-amazon-corretto
# Version確認
$ javac --version
javac 11.0.11
$ java --version
openjdk 11.0.11 2021-04-20 LTS
OpenJDK Runtime Environment Corretto-11.0.11.9.1 (build 11.0.11+9-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.11.9.1 (build 11.0.11+9-LTS, mixed mode)
  • アプリケーションの実行
# spring-sample-0.0.1-SNAPSHOT.jar をコピーした階層で
$ java -jar spring-sample-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.2)

おさらい

  • 構築完了です!
  • はじめに記載した以下の図のように構成されています
    image.png

動作確認

  • http://{WebサーバのIP}/ にアクセスすると、以下の画面が表示されます
    image.png

  • 超泥臭いですが、開発環境で実行したものをAWS上で動作させることができました

  • (このままの構成・デプロイ方法ではないと思いますが)本番環境でどのようにアプリが動いているのかを掴むきっかけになれば幸いです。

以上です。

参考文献

この記事は以下の情報を参考にして執筆しました。


この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com

9
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?