Rails + Nuxt + ECS + GitHub Actions + Terraformで完全SPAのポートフォリオを作成しました

## はじめに
転職活動に伴い、完全に独学で作成したポートフォリオについて記載します。

## 概要

![LP画面.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/eebdbf03-a101-37a8-8375-600ec5e91373.gif)
Mailmentorは、英文ビジネスメール作成の初学者向けの学習アプリです。楽しみながら学べるように、問題に正解するごとにポイントが加算され、ユーザーのレベルが上がる機能を搭載しており、ユーザー同士の競争を通じてモチベーションを高められます。学習形式は、ドラッグ&ドロップでフレーズを並べ替えるインタラクティブな問題が用意されており、正しい並びで文を完成させることが求められます。進捗状況は直感的に理解できるグラフで表示され、英文メール作成のコツやテクニックを紹介する記事の共有も可能です。

## 制作背景
新社会人としてビジネス英語のメールを書く際に、適切なフレーズの選択や丁寧な表現が分からず困った経験があります。この経験を活かし、事前に学習し、自信を持ってメール作成に臨めるようにするアプリを考案しました。
# 機能
### 機能概要
英文をドラッグ&ドロップで並び変え、正しい並び替えにすると正解判定され、ポイントが付与されるようにしました。
![並び替え問題.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/51334443-4536-650b-85f0-baa2767be505.gif)

学習の進捗状況はグラフで確認できます。
![マイページ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/bdf2a6a9-f760-f560-ab86-b5642e9805e1.gif)

記事を投稿し、共有することができます。
![投稿時.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/19d4e6fb-3c93-8c2d-cf7b-8715d349b979.gif)

投稿検索も可能です。
![投稿検索確認.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/09108821-a365-b80c-7ed9-4f26f7823acd.gif)


### 機能一覧
- ユーザーに関連する機能
  - 新規登録
  - ログイン
  - 簡易ログイン
  - ログアウト
  - 登録情報編集、プロフィール画像アップロード、退会
  - 自身のプロフィールページの表示
  - 他ユーザーのプロフィールページの閲覧

- フォローフォロワー機能
  - 他人をフォロー、アンフォロー

- 投稿に関連する機能
  - 記事投稿機能(ジャンルを選択し投稿)
  - 投稿コメント機能(他人の投稿にコメント可能)
  - 投稿表示機能(自身の投稿を確認可能)
  - 投稿削除機能(自身の投稿を削除可能)
  - 投稿検索機能(ジャンル選択で検索可能)

- いいね機能
  - 投稿にいいね可能

- ブックマーク機能
  - 投稿をブックマーク可能

- コメント機能
  - 投稿にコメント
  - 自身のコメント削除

- 通知機能
  - 投稿にいいね、コメント時に通知

- 英語学習に関する機能
  - 英文メール基礎問題を確認するとポイントが付与
  - 英文並び替え問題に正解するとポイントが付与
  - 英文をドラッグ&ドロップで並び変え、正しい並び替えにすると正解判定され、ポイントが付与
  - 各問題に正解すると、その問題は「正解済み」とマークされ、誤答の場合は「不正解」と表示される

- レベルUP機能
  - 記事投稿、基礎チェック問題の確認、英文並び替え問題で正解した獲得したポイントによりレベルアップ

- 学習進捗管理機能
  - 基礎チェック問題の確認状況、英文並び替え問題のクリア状況が円グラフで確認できる

- その他機能
  - ページネーション
  - レスポンシブデザイン

## 使用技術
| フロントエンド
----|
| Nuxt.js(SPA)  |
| Vuetify |
| axios(バックエンドとの非同期通信) |
| eslint/prettier(静的解析、フォーマッター) |


<br />

| バックエンド |
----|
| Ruby 3.1.3 |
| Rails 7.0.4 |
| RuboCop(静的解析、フォーマッター) |
| RSpec(自動テスト) |
| Nginx(Webサーバー) |
| Puma(APサーバー) |
| MySQL 8.0.31(データベース) |

<br />

| インフラ |
----|
| Docker/docker-compose |
| AWS（ECR,ECS,Fargate,VPC,S3,Route53,ALB,RDS,ACM,SSM,CloudWatch） |
| Terraform(インフラのコード管理) |
| Github Actions(RSpec自動テスト,自動デプロイ) |



## インフラ構成図
![AWS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/abd8c028-5239-85c8-b2ad-8b3344d741a7.png)




## ER図
![ER図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/7a65d469-76d2-a64d-8144-3c3b8dcc2cf0.png)

## 工夫した点
### フロントエンド
 - Nuxt.jsによる完全SPA化
 - UIフレームワークにVuetifyを使用し、整ったUIを作成
 - VuetifyのGridシステムを利用し、レスポンシブデザイン設計
 - ESLint/Prettierを利用して、読みやすいコード作成
 - LPページを設け、ユーザーのスクロールを促すような背景デザインを作成
### バックエンド
 - バックエンドとフロントエンドを完全に分離し、API通信を実装
 - N+1問題を考慮した実装
 - クイズ問題をseedで投入
 - RSpecを利用して、正常系テスト・異常系テストを実装
### インフラ
 - Rails7(nginx + puma) + Nuxt.js + MysqlをECS(Fargate)環境で動作
 - GitHub Actionsを用いてCI/CDパイプラインを構築(RSpec自動テスト,自動デプロイ)
 - terraformによるインフラのコード化


## 制作の進め方
railsチュートリアル、プロゲート、ドットインストールが完了した上で以下のステップで開発しました。railsチュートリアル卒業レベルの私では序盤でSPAの構成にするのは難しいと感じ、railsは通常モードで起動しました。railsチュートリアルで教わったことベースにし、機能を実装していく方式を取りました。フロント側はhtml.erbファイルで大まかに作成し、html.erbをNuxt.js(vue.js)へ以降していく流れにしました。github actionsについては早い段階でrspecのみ導入し、恩恵を受けることができます。AWSの構築は終盤で行なっています。AWSは従量課金制のため序盤で構成してしまうとインフラ費用が早い段階で発生するためです。herokuやrenderへのデプロイは実施していませんが、AWSを構築する前にdocker-composeを用いてプロダクション環境を再現したコンテナ起動を行い動作チェックしています。

- 第1段階
  - 設計 (画面遷移図、画面設計図、ER図)
  - 機能実装
  - rspecテスト作成
  - github actions導入（rspecのみ）
  - フロント側はhtml.erbファイルで大まかに作成

- 第2段階
  - Nuxt.js導入SPA化
  - Docker/docker-compose導入
  - html.erbをvue.jsへ以降し、Vuetifyを用いてUI/UXをブラッシュアップ

- 第3段階
  - AWSへデプロイ（ECR,ECS,Fargate,VPC,S3,Route53,ALB,RDS,ACM,SSM,CloudWatch）
  - Terraformによるインフラのコード化
  - github actionsにAWSへのデプロイstep追加

## 技術選定理由
:::note info

- バックエンドの言語については、Rubyを採用しました。

  日本発の言語であり、日本語のドキュメントが豊富なため。

- バックエンドのフレームワークについては、Ruby on Railsを採用しました。

  比較的速く・簡単に実装できるため、中小規模のアプリを短期間で作成することを目指すには最適と考えたため。


- JSフレームワークについては、以下の理由によりVue.js（Nuxt.js）を採用しました。

  Nuxt.jsを含めても学習コストが高くない。
  実装例が多いので再現性が高い。
  個人開発なので大規模ではない。


- Webサーバーについて

  Apacheとnginxのどちらを採用するか迷いましたが、nginxは高トラフィックでもリソース使用量を低く抑えられる点を評価しました。設定がシンプルで管理しやすい点も評価しました。


- APサーバーについて

  Rails5.2からUnicornではなくPumaが標準のAPサーバーになり、あえてUnicornに変える必要もないと思ったため、Pumaを採用しました。

- インフラについては、以下の理由によりAWSを採用しています。

  現在のトレンドはサーバー仮想化ではなくコンテナ型仮想化に移っているので、Fargateのコンテナ基盤を使ったサービスを評価しました。

- CI/CDについては、以下の理由により今回はGitHub Actionsを採用しました。

  GitHubリポジトリに直接統合されているため、追加のサービスやツールを導入する必要がなく、コードの管理と自動化プロセスが同じ場所で行えるため。

- Terraformについては、以下の理由により採用しています。

  Gitによるバージョン管理に対応していること。
  今後同様のインフラ環境を構築する際の工数削減効果がある。

:::

## 学習教材
動画で学習することが好きなので、Udemyの教材をメインに学習しました。
- バックエンド

https://railstutorial.jp/screencast

https://leanpub.com/everydayrailsrspec-jp


- フロントエンド

https://www.udemy.com/course/vue-js-complete-guide/?couponCode=24T5FS31824

https://www.udemy.com/course/jwt-login-authentication-with-railsapi-nuxtjs/?couponCode=24T5FS31824

- インフラ

https://www.udemy.com/course/ecsfargate/?couponCode=24T5FS31824

https://www.udemy.com/course/aws-and-infra/?couponCode=24T5FS31824

https://www.udemy.com/course/iac-with-terraform/?couponCode=24T5FS31824

https://www.udemy.com/course/devops-gha-aws-infra/?couponCode=24T5FS31824


https://www.amazon.co.jp/AWS%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E6%A7%8B%E7%AF%89%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E5%AE%89%E5%85%A8%E3%81%A7%E5%A0%85%E7%89%A2%E3%81%AA%E6%9C%AC%E7%95%AA%E7%92%B0%E5%A2%83%E3%81%AE%E3%81%A4%E3%81%8F%E3%82%8A%E6%96%B9-%E4%B8%AD%E5%9E%A3-%E5%81%A5%E5%BF%97/dp/4798178004/ref=tmm_pap_swatch_0?_encoding=UTF8&dib_tag=se&dib=eyJ2IjoiMSJ9.js2C7MbNWc2DqsORyv9AH5sEQ3QdNLIkdRcqr42KMVj-PfoBpemc_xStCXDHHlc4fLy55m9PYr4VZCHqYYbHDvPI8xgboV8Wu0SOjCFwjw_NqjCWiB1Deij28X2efKJq7w3LMz4AlQAnaRZwEVLa4VLiHFBS0x9go4fWJvXkAPgxXkcdnp2AhjUqF-Zmspojnde-6AjnIhu4NS8E-rbx1VajDDrnSIkI8Ti1ydEAKIb66MrHOTTFkxOBU3wdOvF_.m9RZwNFjecZ0apGOZ3vtOat0IQqj6bWUK3rz1O_JvJ0&qid=1710740074&sr=8-2

![スクリーンショット 2024-03-18 14.36.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739138/24936291-4b93-41c8-905e-6f46474104a2.png)


- Docker

https://www.udemy.com/course/aidocker/