Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
411
Help us understand the problem. What is going on with this article?
@kuromitsu0104

【独学・未経験】Nuxt.js, Rails, Docker, AWS ECS(Fargate), TerraformなSPAポートフォリオを作成しました。

はじめに

プログラミング歴半年(独学)の実務未経験者がSPAなポートフォリオを制作しましたので紹介していきたいと思います!
今後もアップデートしていくのでフィードバックなど頂けますと嬉しいです。
記事の最後には、お世話になったWebサイトや教材をまとめておきましたので参考になれば幸いです。

作者のスペック

年齢は27歳で今までにプログラミング経験は全くなし。
サーバーサイドエンジニアを目指してプログラミング学習中の初学者です。
本記事を執筆している時点でプログラミング学習期間は半年。(2021/1/29時点)
ポートフォリオに関わる技術のキャッチアップをしながら約4ヶ月程かけて完成させました。

ポートフォリオ制作に着手した時点では、ProgateとRailsチュートリアルを終えた程度の実力。
至る所に詰みポイントがありひたすらググりまくって問題解決してました。(Google先生は神)

アプリの概要

制作したアプリケーションがこちら。

https://gadget-community.com(3/28 公開停止しました)

GitHubリポジトリ

『ガジェコミ!』はガジェット好きが集まれるSNS型のWebアプリケーションです。

簡単に言ってしまえば『Twitterクローン』に近いものなので、SNSに必要な機能を重点的に実装済み。

スマホ利用を想定しているのでモバイルからも気軽にお試し下さい!(ゲストログイン有ります)

トップページ

toppage.png

レスポンシブ対応

スマホ利用も想定したUI設計。

responsive.gif

Ajax処理

ネストした要素でもAjaxに動作します。

例) 『コメントアイコンをタップ → コメント欄を表示 → 既にあるコメントに返信』
post_comment_reply.gif

例) 『コメントを削除』
post_comment_delete.gif

ポートフォリオに使用した技術

各バージョン

  • Ruby 2.7.1
  • Rails 6.0.3.4
  • nuxt 2.14.6
  • @nuxtjs/vuetify 1.11.2
  • Docker 19.03.13
  • docker-compose 1.27.4
  • Terraform 0.14.3

フロントエンド

名称 説明
Nuxt.js (SSR mode) フロントエンドフレームワーク
Vuetify UIコンポーネント
Firebase Authentication JWTを用いたログイン・ログアウト
  • Vuetifyコンポーネントを導入することで、スマホ利用を想定したレスポンシブデザインを実現。

  • Vuexストアでステート管理。

  • 個人情報(パスワード)は、外部API(Firebase Authentication)に保存する仕組みで、外部APIで発行されるJWTをCookieに保存してログイン・ログアウト機能を実装しました。

  • 未ログイン状態でアクセスして欲しくないページ( /users/editなど )へのアクセス対策には、Nuxt.jsのmiddlewareを活用することで自動的にリダイレクトするようにしました。

  • ログイン状態でアクセスして欲しくないページ (ログインページ, 新規作成ページ) へのアクセスも同じくリダイレクトします。

バックエンド

名称 説明
Rails (API mode) APIサーバーとして利用
PostgreSQL データベース
  • RailsはAPIサーバーとして利用しており、フロントエンドコンテナからのリクエストに対してJSONデータを返しています。

  • 画像データはActiveStorage経由でS3バケットに保存。

  • その他のデータはRDSに保存。

  • 個人情報(ログインパスワード)は外部API(Firebase Authentication)にのみ保存しており、バックエンド(Rails)には保存されません。

テストコード

名称 説明
Jest フロントエンドテスト, Vuexストアの動作を少しだけ
RSpec バックエンドテスト, バリデーションとアソシエーションのテストのみ
  • CodePipelineのTestステージで実行するテストコードです。

インフラ

名称 説明
ECS Fargate サーバーレスな本番環境, オートスケール
CodePipeline CI/CD環境
RDS 本番用DB(PostgreSQL)
Docker, Docker-compose コンテナ環境
Github バージョン管理
Terraform 本番用インフラをコード管理
  • ローカル開発環境からデプロイまで一貫してDockerを使用。

  • ALBを通すことで常時SSL通信化。

  • CodePipelineは、 『Sourceステージ => Testステージ => Buildステージ => Deployステージ』の順で実行され、Testステージで問題が発生した場合は当該ソースでのDeployは実行されません。

  • 本番環境の環境変数については SSM で管理。『システム環境変数 => Terraform => SSM => 各AWSサービス』というフローで環境変数を受け渡しています。

インフラ構成図

インフラの全体像をまとめたものがこちら。
RDSにはPostgreSQLを採用し、画像を除いたデータを保管。
画像データはS3に保管しています。

スクリーンショット 2021-01-26 19.28.33.png

ER図

一貫性のあるテーブル名称を意識しました。

ER_latest.png

アプリの機能紹介

0. 機能一覧

機能名 説明
ユーザー機能 新規登録、登録内容変更、アバター登録、ログイン、ログアウト、フォロー
つぶやき機能 投稿、編集、削除、画像複数枚登録
つぶやきコメント機能 つぶやきに対してコメント投稿、コメントへのリプライ投稿、削除、画像複数枚登録
つぶやきいいね機能 つぶやきをいいねできる、マイページのいいねタブにいいねしたつぶやきを一覧表示
掲示板機能 質問掲示板、雑談掲示板の作成、編集、削除、画像複数枚登録
掲示板コメント機能 掲示板に対してコメント投稿、コメントへのリプライ投稿、削除、画像複数枚登録
私物ガジェット機能 登録、編集、削除、画像複数枚登録
フィード機能 つぶやき新着表示、タイムライン表示、タグフィード表示
タグ管理機能 つぶやき・掲示板・私物ガジェットにはタグを登録可能、タグをタップしてタグ詳細ページを表示、タグ詳細ページではタグを含むコンテンツを表示
検索機能 各コンテンツを検索可能
通知機能 つぶやきにいいね・コメント、掲示板にコメント、他ユーザーからフォローされると通知を表示
管理者モード Godmode のトグルスイッチをONにすると、一時的に管理者権限が有効化、各コンテンツの削除メニューが表示される

1. ユーザー機能

登録・編集・削除

メールアドレスとパスワードを入力するだけでアカウント作成できます。
メールアドレス確認機能は未実装。

VeeValidateを使用してフォームにバリデーションを設定しています。

user_create.gif

詳細設定ページで登録情報を編集できます。

user_edit.gif

ユーザーにはアバターを設定できます。

user_avatar.gif

アバター画像は各コンテンツで表示されます。

user_avatar_view.png

2. つぶやき機能

投稿・編集・削除

つぶやき作成は即時反映されます。
post_create.gif

つぶやき編集は即時反映されます。

post_edit.gif

つぶやき削除は即時反映されます。

post_delete.gif

タグ付け

つぶやきにはタグを複数登録できます。

post_tag.gif

コメント

つぶやきにはコメントすることができます。

post_comment_create.gif

コメントに返信できます。

post_comment_reply.gif

コメントは削除のみ可能です。編集機能はありません。
親コメントを削除すると子コメントも削除されます。

post_comment_delete.gif

いいね

つぶやきにいいねできます。

post_like.gif

3. 掲示板機能

作成・編集・削除

掲示板作成は即時反映されます。

board_create.gif

掲示板編集は即時反映されます。

board_edit.gif

掲示板削除は即時反映されます。

board_delete.gif

タグ付け

掲示板にはタグを複数登録できます。

board_tag.gif

掲示板タイプ

『雑談』『質問』を選択できます。

board_type.gif

コメント

掲示板にはコメントすることができます。

board_comment.gif

コメントに返信できます。

board_comment_reply.gif

コメントは削除のみ可能です。編集機能はありません。
親コメントを削除すると子コメントも削除されます。

board_comment_delete.gif

4. 私物ガジェット機能

登録・編集・削除

自分の私物ガジェットやお気に入りアイテムを登録できます。
登録したガジェットは一覧ページでは『みんなのガジェット』として新着表示されます。

gadget_create.gif

ガジェット編集は即時反映されます。

gadget_edit.gif

ガジェット削除は即時反映されます。

gadget_delete.gif

タグ付け

私物ガジェットにはタグを複数登録できます。

gadget_tag.gif

5. フィード機能

つぶやきを一覧表示します。
無限スクロールで順次読み込みます。

<タブによって表示する内容が異なります>

  • 新着順 => 全てのつぶやきを新着順で表示
  • タイムライン => フォロー済みユーザーのつぶやきのみ新着順で表示
  • タグフィード => フォロー済みタグを含むつぶやきのみ新着順で表示

feed_new.gif

6. タグ管理機能

タグをフォローすることができます。
タグフィードに表示したいタグをフォローします。

tag_follow.gif

つぶやき・掲示板・私物ガジェットはタグ付けすることができます。
タグをタップするとタグ詳細ページに遷移し、タグを含むつぶやき・掲示板・私物ガジェット・フォローしているユーザーの一覧を表示します。

tag_show.gif

7. 検索機能

検索ページでは、検索フォームに入力した内容に合わせて結果がリアルタイムに表示される機能を実装しております。

search.gif

8. 通知機能

つぶやき・掲示板・ユーザーフォローにおいて、イベントが発生すると通知が表示されます。

新着通知

新しい通知が発生すると、ヘッダー内のベルアイコンにバッジが表示されます。
タップすると新しい通知がリスト表示され、通知をタップするとイベント発生元へ画面遷移します。

notices.gif

通知一覧

通知一覧をタップすると一覧ページへ画面遷移します。
通知一覧ページでは、今まで受け取った全ての通知を表示します。

notices_index.gif

9. ゲストユーザー機能

■追記(2/19)
ゲストユーザー機能の仕様を変更しました。
変更点)ブラウザ再読み込みでログアウトするようになりました。
→ RailsAPIからユーザー情報を取得して、Nuxt.jsのVuexストアに値を保存しているため。
→ FirebaseのJWTをCookieに保存したログイン・ログアウトの永続化は、ゲストユーザーからは除去しました。
→ ログイン状態だとFirebaseAuthenticationユーザーを削除する為に必要な値がデベロッパーツールから確認できてしまうため。
→ FirebaseAuthenticationユーザーを削除すると、ゲストユーザーログイン機能が動作しなくなるため。

ユーザー専用機能を簡単に利用できるように、ゲストユーザーログイン機能を実装しています。

『ゲストユーザーとしてログイン』をタップするだけです。

guest_loggin.gif

未ログイン状態でユーザー専用機能にアクセスすると、ゲストユーザーログインを促すダイアログを表示するようにしております。

guest_loggin_support.gif

10. God mode

(1/31 追記)
・削除を実行できないように修正しました。
・管理メニューを確認するための機能として残します。
(2/3 追記)
・特定のメールアドレスを持つユーザーのみ削除を実行できるように修正しました。

一時的に管理者権限を有効にするモードです。(管理者という概念が存在することを確認して頂くためのモードです。)

DB内 の Userモデルの adminカラム の true/false で 各ユーザーの管理者権限を管理しておりますが、God modeではVuexストアの値を一時的に変更して管理者権限を有効化しています。(DB上には保存されないのでブラウザ再読み込みでfalseに戻ります。)

つぶやき・掲示板・私物ガジェットにはそれぞれ『管理メニュー』が設定されており、作成者本人にのみ表示される仕組みです。

スクリーンショット 2021-01-29 21.04.32.png

God mode を有効化にすると他のユーザーが作成したコンテンツでも『管理メニュー』を表示するようになり、『削除のみ』実行可能となります。

admin_mode.gif

制作を終えてみて

ポートフォリオのアップデートは今後も行いますが、いったん区切りがついたのでホッとしています。

制作中に苦労したポイントをまとめてみると以下の内容で、主に初期学習のタイミングで壁が何度も現れました。

内容
フロントエンドとバックエンドを分離した開発環境の構築 仮想コンテナの基礎知識やポートフォワーディングでつまりました。初めからdocker-composeを使うことをオススメします。
環境変数の受け渡し ローカル環境、本番環境のインフラ構成に合わせて環境変数の渡し方に工夫が必要でした。
Vuetifyモジュールの導入 Nuxt.jsの初期セットアップでVuetifyを選択するとエラー発生。VuetifyなしでNuxt.jsをセットアップ + 後からVuetifyを導入 + おまじないが必要で詰みました。
SSRモードで動作するNuxt.jsのライフサイクル SSRでSPA用コードを実行するとライフサイクルが一部違うので正常に動作しません。
AxiosモジュールのSSRモードでの挙動 SPAとSSRではAxiosのエンドポイントの設定に違いがあり詰みました。
Firebase Authenticationの導入 SSRモードでの解説記事が少なく、動作させるまでに苦労しました。
SSRモードでは動作しないプラグイン ポートフォリオで利用した『@johmun/vue-tags-input』がSSRモードでは動作しなかったので、特別なおまじないが必要でした。
親コンポーネントと子コンポーネントのデータ受け渡し props, emitの概念の理解に苦戦しました。
Vuexストアの扱い方 断片的な解説記事が多くて理解するのに時間が掛かりました。
終わらないN+1対策 アソシエーションの絡んだデータ取得をするたびに苦労しました。
ECS Fargateでのインフラ構築 FargateはSSHできないのでエラーログの取得やトラブルシュートに手間取りました。CloudWatchなどを利用して確実にログを取れる環境を作らないと、どこに問題があってコンテナが動いていないのか判断できなくて詰みます。

特に厳しかったのがECSデプロイでして、途中何度も諦めそうになりましたが何とかやり終えることができました...。(インフラ難しい)

何とか形になったものの、書いているコードは実務レベルから比べると『その場しのぎ』程度だと思いますし、
プログラミングにおける基礎知識が抜けていると思い知らされる場面も多々ありました。(特に学習初期の理解力)

正直なところ、Nuxt.js や Rails という『ツール』を何となく使えている、というのが現時点での実力だと思います。

今後について

ポートフォリオが完成したので就活を始めるために準備を進めています!

就活以外では、課題である基礎力を伸ばすために基本情報技術者やJavaSliverなどの取得を目指して資格勉強も進めていくつもりです。(オススメ教材などあれば教えて欲しいです)

ただのポートフォリオ紹介記事ですが、最後までお付き合い頂きましてありがとうございました!

Twitterもやってますので是非フォローもよろしくお願いします!

関連リンク

お世話になった書籍や教材

ポートフォリオ制作中に何度もお世話になった資料一覧です。
これがなければ完成できていなかったので本当に感謝しています。ありがとうございました!

媒体 資料名 学習内容
Web Progate Ruby, Rails, HTML, CSS, JavaScript...などの基礎を学習
Web Railsチュートリアル いわずもがな、Railsの基礎、Herokuデプロイ、AWS S3、GitHubの扱いなどを学習
Web JavaScript Primer DOM操作以外のJavaScriptの基礎を学習
Web Rails + Nuxt.js + Docker なアプリを作ってみよう 神記事です。めちゃめちゃ参考になりました。ただしSPAモードなのでSSRモードで制作する場合は工夫が必要。
Web 独学プログラマ (Docker+Rails6+Nuxt.js+PostgreSQL)=>Heroku 環境構築~デプロイまでの手順書 神記事です。特に環境構築の手法がめちゃめちゃ参考になります。
Web Pikawaka Railsの基礎はここ見れば大体全部載ってます。マジでわかりやすくて助かりました。
Web SSRモードのNuxtでのFirebase認証 この記事とGitHubリポジトリがなければ実装するの諦めてました。本当にありがとうございます。
Web b1tblog Vue.jsの解説記事が多数掲載されています。
書籍 たのしいRuby Rubyの基礎を学習
書籍 Ruby on Rails速習実践ガイド Railsでよく使うコマンドやRailsの基礎を学習
書籍 プロを目指す人のためのRuby入門 実践的なRubyについて学習
書籍 Rubyによるクローラー開発技法 Rubyだけでスクレイピングアプリを作れます。学んだ基礎知識をアウトプットするために使用しました。
書籍 Nuxt.jsビギナーズガイド Nuxt.jsの基礎学習。Vue.jsの経験がないと難しいかも。
書籍 速習Vue.js3 Vue.jsの基礎学習。単一コンポーネント形式のサンプルが少ないので、これだけでは不十分かも。
書籍 実践Terraform AWSにおけるシステム設計とベストプラクティス 神本。これがなければECSデプロイできませんでした。感謝しています。
書籍 はじめての人のためのTerraform for AWS Terraformを全く触ったことない人向けの書籍。サンプルコードがちゃんと動作するので感じを掴むのに最適。
書籍 CircleCI実践入門 CI/CDってなに?という状態から勘所を掴むために使用。結局CodePipelineで実装したけど自動テストの雰囲気が掴めて良かった。
書籍 Amazon Web Services 基礎からのネットワーク&サーバー構築 AWSの基礎学習にぴったり。EC2での解説なのでECSについては別途学習する必要あり。
書籍 Docker/Kubernetes実践コンテナ開発入門 Dockerの基礎学習。初心者向けの章節まで読めば十分でした。
書籍 ゼロからはじめるデータベース操作 実践的なSQLを学習。
書籍 Webを支える技術 ネットワークの概念がイマイチ理解できてないときに使用。
書籍 GitHub実践入門 GitHubの基礎学習
411
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
411
Help us understand the problem. What is going on with this article?