【AWS】初学者がAWS使用し初めてデプロイして詰まったポイントまとめてみた！！（React + Rails + MySQL）

# はじめに
今回初めてAWSを使用しクローンアプリをデプロイしたので、大まかな流れと詰まった部分、参考にした記事を紹介できればと思います。
具体的な方法は記述しませんので添付の記事を見ていただければと思います！
この記事では私と同じ構成で初めてデプロイしよう！という方が見ていただければ、エラー対処の一助になることができるかと思いますのでよければデプロイ前に一度見ていただければと思います！

今回私が使用した技術と環境は下記になります。
- 実施環境
M1 Mac
Amazon Linux 2023

- 使用技術
1.React(node:16.15.0) 
2.Ruby:3.1.2
3.Ruby on Rails:7.0.3
4.MySQL:5.7
5.AWS各種サービス
6.nginx:1.24.0
7.Git Hub
8.axios

- ディレクトリ構成
```
アプリ名
├── backend（rails newで作成したAPIモードのRails）
└── frontend（npm-create-appで作成したReact）
```

## 今回のデプロイまでの流れ

1. ローカル環境で動かすことのできるアプリの作成。（今回はReact+Rails+MySQLで作成）
1. GitHubにpushしリモートリポジトリを最新版にしておく
1. AWSで構築するインフラ構成図を考える
1. AWSでVPCの作成
1. サブネットの作成
1. インターネットゲートウェイの作成
1. ルーティングの設定
1. EC2インスタンスの作成
1. インスタンスの環境構築
1. Route５３でのドメインの取得と設定
1. RDSでのデータサーバーの構築
1. ELBでの冗長化
1. SSL化でのhttps通信
1. Git Hub actionsを使用したCI/CDの構築


## 今回作成したAWSの構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741017/df057dd1-46ad-60a5-cd78-55a07e37b7b7.png)

private subnet2つありますが後々RDSもう1つ設置する予定なので記述しております。

## AWS構築
今回ほぼ詰まった部分がインスタンスでの環境構築になります。。。
VPCの作成やサブネット等細かいところが正直これからという方は一度下記UdemyのAWS講座をしてみていただけるとデプロイまでの理解度が全然違うのでおすすめです！
ただし、AWS画面の表示やボタンの位置など結構デザイン等が動画と現在では違っているので、VPCとは何か？といった説明の部分をしっかり聞き、現在のバージョンに対応する部分を探しながら構築していくと勉強になるかと思います！
私もAWS初心者で知識0でこの動画からスタートしました！
[Udemyおすすめ講座](https://www.udemy.com/course/aws-and-infra/)

ちなみに上記動画ではApacheをインストールしWordPressを表示していますが、今回私はApacheではなく、nginxを採用しRails+Reactを表示しました！

## 詰まった部分①Rubyのインストール
おそらく初めてAWS触られる方はインスタンスタイプを無料利用枠のものを使用されるかと思います。
t2microなどはCPUなどが小さいのでインストールなどCPU多く使うものは途中で止まってしまうことや、めちゃくちゃ時間がかかってしまうことがあります。
環境構築するなんて初学者からしたらプログラミング勉強始めのわけわからない状態でなんとか自身のパソコンにRubyの環境を作ったりしたので手順なども何も覚えていないと思います、、、
記事参考にし実行しても止まってしまう。。。実際私がそうでした、、、しかも違うOSになるので色々見て回ることになると思います。
インストールできない場合は下記コマンド実行してみてもらえればと思います。

```
mkdir ~/tmp　
TMPDIR=~/tmp rbenv install 3.1.2　
```
"No space left on device" というエラーが出てしまう時は使用状況が逼迫しておりインストールができないことを表しています。
上記コマンドはインストールの際には一時ファイルが作成されるのでそのファイルを~/tmp ディレクトリを一時ファイルの保存場所として指定しインストールしています。
/home ディレクトリは通常、/tmpよりも大きい容量を持つため、こちらを利用することで "No space left on device" の問題を回避できるはずです。
この後もCPUが逼迫してしまいエラーも出ずに止まってしまうこともあるかと思います。
その際は都度、AWSのEC2からインスタンス選択し、モニタリング部分をご確認ください。
その場合、CPU使用率が100％近くになっていることがあるかもしれません。
もしくはコマンド実行できる状態であれば、下記コマンドでも確認できます。
```
df -h
```
このコマンド実行し各ファイルの使用状況確認できます。
インストールが止まってしまい、コントロールCで中断した際など確認してみるといいかもしれません。

Rails環境構築まではこの記事がとてもわかりやすく参考にさせていただきました！
[EC2+RDSでRails環境構築](https://zenn.dev/ito110/scraps/81b8dd657a5c6b)

## 詰まった部分②MySQLのインストール
ここはいまだに正直よくわからない部分が多く呪文のようになってしまっています、、、
記事ではよくデフォルトでインストールされているMariaDBを削除等出ますが、私の実行環境ではデフォルトで確認しても競合するようなMariaDBはなく、MySQL自体が競合してしまい、何度もエラー出しました、、、
SSHにログインしてまず下記コマンド使用しMySQLとMariaDBを確認してみてください。
```
sudo yum list installed | grep mysql
```
なければ下記コマンドでインストールできます。
```
sudo dnf -y localinstall  https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
```
```
sudo dnf -y install mysql mysql-community-client
```
```
sudo dnf -y install mysql-community-server
```
インストール完了しましたら下記コマンドで起動確認とバージョンの確認してみてください！
```
sudo service mysqld strat
```
```
sudo systemctl status mysqld
```
```
mysql --version
```
AmazonLinux2023にてMySQLインストールするのは僕自身深掘りが必要です、、、
下記MySQLインストールの際に参考にした記事になります！
[EC2+RDSでRails環境構築 Zenn](https://zenn.dev/ito110/scraps/81b8dd657a5c6b)
[EC2+RDSでrailsの環境構築 Qiita](https://qiita.com/koyama_0122/items/7da5d05b5cd1474ec41b)
[【Rails6.0×RDS(MySQL8.0)×Nginx×Unicorn】AWSへのデプロイ手順まとめ](https://qiita.com/k-mashi/items/21871c82d385648b4bae)

## 詰まった部分③nginxの設定
ここもめちゃくちゃ詰まりました。。。
まずnginxとは？から始まります。。。
nginxはめちゃくちゃ簡単にまとめるとWebサーバーでロードバランサのように処理を振り分けてくれるソフトです。
今回ReactとRailsの構成で作成しているのでrootではReactの画面が表示され、ユーザのクリックなどのアクションに応じてReactがRailsのAPI URLを叩くような構成です。
最終的にRails側はPumaのアプリケーションサーバを使用し/api/というリクエストは全てRails側の処理になるよう記述しました。ここでローカルで開発していた時にAPIモードではrouteに名前空間をつけるというものの意味がわかりました！

最終的には下記のような記述になりました。
サーバ８０番ポートで待っているのがReactのnpx run buildで作成したbuildディレクトリの中にあるindex.htmlをserver_nameの部分のドメイン名でのアクセスが来た時のrootとして指定しています。
そして、location /api/と記述のある部分でドメイン名/api/というリクエストをRailsに投げるように設定しています。
```nginx
error_log  /var/www/アプリ名log/nginx.error.log;
access_log /var/www/アプリ名/log/nginx.access.log;
upstream rails_api {
    server unix:/var/www/アプリ名/backend/tmp/sockets/puma.sock;
}
server {
    listen 80;
    client_max_body_size 4G;
    server_name アプリ名.com;
    charset utf-8;
    keepalive_timeout 30;
    # Location of our static files
    location / {
  root /var/www/アプリ名/frontend/build;
        try_files $uri $uri/ =404;
    }
    location /api/ {
        proxy_pass http://rails_api;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
    error_page  400 403 404  /40x.html;
    location = /40x.html {
      root   /usr/share/nginx/html;
    }
}
```

まだまだ勉強不足は否めない部分ですね、、、
下記参考にした記事になります！
[nginxについて。フロントとバックエンドで繋ぐ先を振り分ける](https://teratail.com/questions/341894)
[ReactとRailsのアプリを一つのEC2にデプロイする。React編](https://qiita.com/inoue_yuki/items/0536d40ee4ba166e5202)


## 詰まった部分④Railsの自動起動設定
ここも全く未知の領域がたくさん出てきました。
nginxなどはenableなどで自動起動設定できますが、Railsをpumaで起動する際にはそのようなコマンドがないので、下記コマンドで自動起動設定用のファイルを作成する必要があります。
etc/systemd/system以下にserviceというファイルを作成します。ここに諸々の記述をすることでrails.serviceをenableにすることができます。
```
sudo vi /etc/systemd/system/rails.service
```
中身は下記のように記述しました。
WorkingDirectoryの部分でRailsアプリの存在する場所を指定しExecStartの部分でどのようなコマンドを実行するかを記述しています。今回はpuma使用するのでrails sではないですが、rails sで-b 0.0.0.0でバインドして起動するやり方もあります！
```systemd
[Unit]
Description=Rails Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/var/www/アプリ名/backend
Environment="PATH=/home/ec2-user/.rbenv/shims:/home/ec2-user/.rbenv/bin:$PATH"
ExecStart=/usr/bin/sudo -u ec2-user -H /home/ec2-user/.rbenv/shims/bundle exec puma -e production -b unix:///var/www/アプリ名/backend/tmp/sockets/puma.sock
TimeoutSec=70
Restart=always
[Install]
WantedBy=multi-user.target
```
また、pumaで実行する際はほどの起動コマンド実行した後にbackend/tmp/sockets配下にpuma.sockが出来上がっているかどうか確認ください。このファイルがソケットになり、nginxでも指定しているので作成されていなければrails繋げることできません。

この部分に関しては自身のググり力が足りずChatGPTと壁打ちして作成しました、、、
環境を改めて作成したことによる副産物だと思い、今後も精進します、、、

## 詰まった部分⑤ドメインで検索しても思った挙動が得られずエラーが出る
具体的に詰まったというよりもなぜこのエラーが出るのか解析に時間がかかった部分になります。
特にロードバランサ設置しSSL化を行いhttps通信可能にしてから、Reactの静的画面は表示されるが、Railsへのアクセスが悉く400番台のエラーになってしまったり、そもそも502エラーで表示画面が見つからなかったりしました。

- まず400番台のエラーはリクエストがサーバーによって拒否されていたりなどのエラーになります。
私の場合はロードバランサに対する知見が浅く同じインスタンス内のReactにアクセスしているのはhttpsなのでその中ですでに承認されているので大丈夫だと思い、ReactからRailsへのアクセスは内部的なものなのでhttp通信で大丈夫だと思っていました。しかし、その場合httpsとhttpの通信が混在するというエラーが出ます。
なので、ReactからRailsへのリクエストを飛ばすaxiosのURLもhttpsにする必要があります。

- 次に502エラーで画面表示がされない。この問題はこの後の参考にした記事を見ていただくととてもわかりやすいのでぜひ見ていただきたいです。私の場合はロードバランサとバックエンドWebサーバーのタイムアウト値が関係しておりました。
今一度nginxの設定ファイルを見てみて欲しいのですが、keepalive_timeout 30;このような記述があると思います。この設定が、ロードバランサ側のアイドルタイムアウトよりも明らかに小さく設定されているとページに到達しないことがあります。私の場合は何もわからず記事を参考に作成していたのでとりあえず書いとくかという気持ちで5と記述していましたが30に変更するだけで無事に表示されました。

下記参考にした記事になります
ロードバランサ設置後に502エラー出た際はぜひ参考にしてみてください！
[「ALB 502 エラーの原因切り分けYes/No 診断」を作ってみた](https://dev.classmethod.jp/articles/alb-502error-cause-yes-no-chart/#result-a)
[今さら聞けないAWSでロードバランサーを使ったWEBサイト構築手順(ロードバランサー編)](https://qiita.com/ksawada1979/items/375cc4f7a2c5b59a89f2)

# おわりに
もっとたくさん詰まった部分はあったのですが、あまりにも長くなるので一番解析に時間がかかった部分抜粋して載せております。
私と同じく初学者でデプロイまで辿り着いたがエラー多発している方の力に少しでもなれれば嬉しく思います。
また、学習中ですので誤った表現や認識違い等ありましたらコメントで教えていただけると助かります。
最後までご覧いただきありがとうございました！！