【個人開発】実務未経験でDocker × Laravel × AWSを使ってWebアプリを開発した話

## 0.はじめに
**実務未経験でDocker × Laravel × Vue.js × AWSを使ってWebアプリを開発した話をします。**

右も左もわからない中、なんとか手探りでSNSサービスの開発に成功できました。
同じく**実務未経験でWebエンジニアを目指す**方々の<font color="SandyBrown">希望</font>になれたらいいなと思います。

## 1.簡単な自己紹介 
- 東京にてバックエンドエンジニアを目指しております。(広島出身、東京在住)
- 2021年3月からプログラミング学習を本格始動→2021年9月〜2022年2月までポートフォリオ開発をしておりました。
- 趣味はプロ野球観戦(<font color="Red">カープ</font>)、旅行、ゲーム、筋トレで、好きな食べ物は唐揚げです。

私の<font color="DeepSkyBlue">Wantedly</font>ページに詳細を記載してますので、ご覧いただけると幸いです。

https://www.wantedly.com/id/yuuichi_mizuta

## 2.使用技術

### <font color="Red">バックエンド</font>
- **php:7.4-fpm-alpine**
- **Laravel 6.20.34**

### <font color="Red">フロントエンド</font>
- **HTML**
- **CSS**
- **MDBootstrap 4**
- **Vue.js 2.6.14**

### <font color="Red">開発環境</font>
- **Docker 20.10.12 / Docker Compose v2.2.3**
**(nginx, php-fpm, supervisor, mysql 8.0.27)**

### <font color="Red">本番環境</font>
- **AWS：EC2, RDS, VPC, Route 53, ALB, ACM, S3, CloudWatch**
**EC2:(nginx, php-fpm, mysql 8.0.27)**
- **CircleCI**
  **deploy job：git pullデプロイ自動化**
**slack orb:：Slackデプロイ結果通知**

### <font color="Red">使用ツール</font>
- **ソース管理： Git / GitHub**
- **IDE： Visual Studio Code**
- **DBクライアント：TablePlus**
- **ER図, 画面遷移図, インフラ構成図：Cacco, Draw.io**

## 3.開発背景

### <font color="OrangeRed">ポートフォリオを作成した理由</font>
- **PHP, Laravel, Docker, AWS, CircleCIの学習のため**
- **自身の技術力、キャッチアップ力を示す成果物を作成するため**
- **アウトプットしながら効率的に学習するため**
- **今後自身の学んだ事を次々とポートフォリオに反映させていきたいから**

### <font color="OrangeRed">旅行をテーマしたSNSサービスを作成した理由</font>
- **自身の趣味が旅行であったため**
- **同じ趣味同士が繋がり出会いや交友関係を広めることができるため、
今後マッチングやチャットなどの機能追加ができたりと発展性があるため**
- **旅行好きな人が多く存在していて、国内外問わず話題が豊富である**

**<font color="Green">あとはコロナ禍で旅行者数も減少傾向にあるので、このアプリをきっかけに盛り上げれたらいいな、という思いもありました。</font>**

## 4.完成したアプリの紹介

**投稿一覧画面**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/85e91257-4cad-04dd-0076-7281f35fd453.png">

~~<font color="OrangeRed">**URL :**</font> travel-notes.online~~

:::note warn
**＊現在ポートフォリオの方は公開しておりません。<br/>Herokuか、AWSで簡易的なリソース構成で再公開する予定です。**
:::

<font color="OrangeRed">**今回開発したポートフォリオの機能や画面の詳細は以下の記事にまとめましたので、見ていただけたら嬉しいです。**</font>
**↓↓↓**
<font color="OrangeRed">**紹介記事 :**</font> [旅の思い出を共有できるSNSサービス『Travel notes』の紹介](https://qiita.com/yuuichimizuta/items/8f0485da3262f55a35e6)

https://qiita.com/yuuichimizuta/items/8f0485da3262f55a35e6

<font color="OrangeRed">**GitHub :**</font> https://github.com/Yuuichi-M/travel-notes

https://github.com/Yuuichi-M/travel-notes

## 5.画面遷移図について
- Draw.ioというツールで作成しました。

![スクリーンショット 2022-03-07 0.02.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/98cb24ba-9843-957d-86c5-8b95e62251fb.png)

**画面遷移については使いやすさを重視して、複雑にならないようシンプルに構成しました。**

## 6.ERデータベース図について
- こちらもDraw.ioで作成しました。
![スクリーンショット 2022-03-06 23.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/75ddd8d9-b1e2-622a-8d74-ec4decefd7b2.png)

**作成したテーブルの詳細**
|テーブル名|説明|
|:--|:--|
|Users|登録ユーザー, プロフィール情報の管理|
|Articles|投稿された情報の管理|
|Comments|投稿に対するコメントの管理|
|Likes|いいねの管理|
|Follows|Userに紐づくフォロー,フォロワーの管理|
|Categories|Articleに紐づく都道府県カテゴリ|
|Article_Tags|Articleに紐づくタグIDの管理|
|Tags|Article_Tagに紐づくタグの名前の管理|

**テーブルの作成にかなり時間を費やしました。** ER図についても全く書いたことが無かったので、
**外部キー制約とリレーション** について色々な学習サービスの教材でDBについて学習して、
構成することができました。

## 7.開発環境について

**開発環境構成図**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/1f828ef8-5dba-5fde-87b9-7c5f1a3bc479.png" width=90%>

**開発環境はDockerでLEMP環境を構築しました。**
環境構成は以下の通りです。

 - **Docker Image**
   - **Appコンテナ**
     - **nginx, php-fpm, supervisor**
     - **Laravel**
   - **DBコンテナ**
     - **MySQL**
 
**Vue.jsも使用するため、導入しました。**

**<font color="Red">Dockerを使用したLaravelの開発環境構築については以下の記事にまとめております。</font>**
**↓ ↓ ↓**

- **[【Docker+Laravel6メモ】開発環境構築についてまとめてみました](https://qiita.com/yuuichimizuta/private/85015a63a8e53c058cb2)**

https://qiita.com/yuuichimizuta/private/85015a63a8e53c058cb2

## 8.本番環境構成図

![スクリーンショット 2022-04-01 17.07.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/5eb06305-de19-dc99-5230-dda84738f988.png)

**AWSにて本番環境を構築して、開発環境と同じLEMP環境を設定しました。**
**CircleCIを使用した自動デプロイの設定も行いました。**

- **VPC**
  - **Publicサブネット 1a, 1c**
    - **EC2(amazon linux 2) : nginx, php-fpm**
  - **privateサブネット 1a, 1c**
    - **RDS : MySQL**
- **ALB : ロードバランサー**
- **S3 : 画像用ストレージ**
- **ACM : HTTPS化(SSL証明書取得)**
- **Route53 : DNSレコード管理**
- **CircleCI : git pullデプロイの自動化**

<font color="Red">**今回はコストの面も考慮して、上記のようなシンプルな構成で行いました。**</font>

本番環境については、**インフラ周りの理解したかった**ため、**AWS**を選択しました。
構築までに1ヶ月を要し、とにかく**0から理解しなくてはいけなかった**ので大変でした。
何度も迷子になり、色々触って確認、修正するたびに**AWSの各ツールの役割と繋がりを理解していくこと**ができました。

特に<font color="Red">**実務を意識して構築**</font>したので、効率よく学習できました。

- **複数サーバーを構築する事を想定してロードバランサーを設置**
- **VPCのサブネットも複数作成**
- **CricleCIで自動デプロイ設定したので、EC2内で手動デプロイする手間が省けました。**

**<font color="Red">AWSを使用した本番環境構築については以下の記事にまとめております。</font>**
**↓ ↓ ↓**

- **[【AWS＋Laravel】本番環境構築についてまとめてみました](https://qiita.com/yuuichimizuta/items/899251a9cb2dd61dabb0)**

https://qiita.com/yuuichimizuta/items/899251a9cb2dd61dabb0

## 9.開発開始〜完了までにかかった期間

![スクリーンショット 2022-03-10 16.13.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/de7ed0b6-29fe-4883-d731-71ef606ee5e1.png)
![スクリーンショット 2022-03-10 16.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/9438f3bc-420a-d7c7-a146-d69018a7f089.png)
:::

**2021年9月1日にスタートし、2022年2月28日に完成しました。（現在も細かい部分の修正・改良を施しています）**
**開発しながら学習** も行っていたので期間として長くなってしまいました。

1月〜からは本番環境の構築に大苦戦していました。この期間が一番辛かったですが、**2月からMENTAにてお声がけいただいた安達さんのフォローのおかげで、デプロイまで完了できました!**

## 10.Git/GitHubを使用したソース管理

開発初期は**Git Flowでソース管理**をしておりました。

開発後半からは開発スピードを上げるために<font color="Red">**GitHub Flow**</font>を取り入れました。

**以下の記事を参考にしました↓**
[git flowとgithub flowとは？その違いは？](https://qiita.com/mint__/items/bfc58589b5b1e0a1856a)

**作業毎にこまめにブランチを切り、プルリクエストを作成するクセが身につきました。**

## 11.タスクの管理
![スクリーンショット 2022-03-10 17.59.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/d4f2843a-094b-1fd8-e7ca-930435177e72.png)

Notionにてポートフォリオ開発に必要な工程を1つづつばらして管理
**Gitのブランチを切るタイミングも分かるので、とても便利でした。**

## 12.工夫したこと

- <font color="Red">**レイアウト**</font>

**メディアクエリを使い、レスポンシブ対応をしっかり考えて実装したので、スマホでもストレス無く利用できます。**

![スクリーンショット 2022-03-19 1.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/40a5e3d4-852c-c953-29f7-2887a8ac5277.png)
</font>

- <font color="Red">**ログイン前のウェルカム画面**</font>

サービスの簡単な説明＋投稿一覧を表示させようとするとかなり縦長になり、スクロールに疲れてしまったので、
**TOP画像をカルーセルに設定して、横にフェードするようにしました。**

これにより**画面がスッキリ**させることができました。

**以下をご参照ください**
↓↓↓
**[ウェルカム画面](https://qiita.com/yuuichimizuta/private/8f0485da3262f55a35e6#%E3%82%A6%E3%82%A7%E3%83%AB%E3%82%AB%E3%83%A0%E7%94%BB%E9%9D%A2)**

- <font color="Red">**投稿一覧画面**</font>

**Instagramのように画像をメインに表示**させ、インパクト感を出しました。
これにより見た目も綺麗にできたんじゃないかと思います。

また、**Twitterを意識した投稿ボタンを画面左下に設置**しました。
これにより**スマホで利用する際の投稿**がしやすくなります。

以下をご参照ください
↓↓↓
**[投稿一覧画面](https://qiita.com/yuuichimizuta/private/8f0485da3262f55a35e6#%E6%8A%95%E7%A8%BF%E4%B8%80%E8%A6%A7%E7%94%BB%E9%9D%A2)**

- <font color="Red">**N+1問題の解消**</font>
データが多くなると画面が重くなってしまうため、
**Debugbarを使用してSQLの発行回数**を確認しながら実装しました
**loadメソッドを使用。(遅延Eagerロード)**
``` PHP:UserController.php
$user = User::where('name', $name)->first()
            ->load(['articles.user', 'articles.likes', 'articles.tags', 'articles.comments', 'articles.category']);
```

## 13.大変だったこと

- <font color="Red">**レスポンシブ対応**</font>

**SNSサービスなのでスマホで利用する事を想定して開発しておりました。**
その時にレスポンシブ対応できてないと、悪質なサイトと思われても仕方ないくらいひどい画面になるので、**メディアクエリ**などを細部まで使用して、徹底的に対応させました。

何度も何度も幾日も...実装→検証を繰り返したので、**正直バックエンド処理実装の倍以上時間がかかりました。**

AWSデプロイ後もCSSが崩れたので、その修正も大変でした。。

- <font color="Red">**都道府県プルダウン**</font>

**投稿画面で選択できる都道府県一覧**ですが、config配下に配列データを書いたファイルを作成して表示させるみたいな手順の記事が主だったので、それを参考にして作成したのですが、それだと**選択してもデータとして保存されない事象**が起こりました。

どの記事を探しても解決策が無かったため、Techpitでカテゴリ選択の実装がありそうなECサイト作成教材をいくつかやってみたところ、**Seederファイルで配列を作成しDBのCategoriesテーブルに保存して、ArticlesテーブルのCategory_IDを紐付けて登録する**やり方を見つけたので、なんとか実装できました。

**学習時間と合わせると15日近くは格闘していた**ので、大変でした。

- <font color="Red">**検索機能(カテゴリ, キーワード)**</font>

検索機能については学習や共同開発でも実装したことが無かったので、学習サービスや記事からのキャッチアップに長い時間費やしたタスクでした。
ポートフォリオへの実装段階では**検索結果が表じされないエラー**に悩まされ、解決にかなりの時間を要しました。
**カテゴリ検索とキーワード検索をif文で分けて実装し、検索キーワードの値保持など、複雑なコードを書く作業**が多く、苦労しました。

動作がうまくいったときは嬉しさのあまり叫びました。笑

- <font color="Red">**PHPUnitテスト**</font>

PHPUnitテストについても実装したことがなかったので、**公式ドキュメントを軸に様々な記事を参考**にテストコードを書きました。
**Article, User, Login, Register**における必要なテストコードを書きましたが、まだまだ理解不足の点もあるため、今後とも勉強していきます。

- <font color="Red">**AWS**</font>

AWSについては見慣れない用語と概念が多く、それを理解するまでが大変でした。
実際に触ってみて苦労したことは、**セキュリティーグループの設定、ALBとACMを使用したHTTPS化**に苦労しました。

セキュリテーグループの設定は何度も迷子になりながら修正を繰り返しました。**EC2, ALB, RDSに紐付け**しましたが、**ポート番号の設定と各グループとの紐付け**が特に難しかったです。

**ALB**と**ACM**を使用した**HTTPS化**については、**SSL証明書**を発行して、**Route53のエイリアスをAレコードに追加する**やり方を調べるのに苦労しました。CNAMEを追加するだけではHTTPS化しなかったので、そこの理解に時間がかかりました。

- <font color="Red">**CircleCI**</font>

GitHubとの連携までの作業が多く、**publicキーとprivateキーの設定**、**CircleCIの環境変数の設定**など、理解しながら設定するのが大変でした。
**config.ymlの設定**については、様々な記事や公式ドキュメントのテンプレを参考に作成しましたが、ローカルでconfig.ymlの動作確認トするのを忘れてプルリクエスト→マージ時にエラーが出たりと、苦労しました。

その後config.ymlを修正して、ローカルでの動作確認がうまくいき、マージしてデプロイ成功。
自動デプロイ完了により、予定していた開発タスクはすべて完了したので、本当に嬉しかったです！

## 14.今後の課題
- **Sendgridの導入：実際に使用されているメールアドレスで、メール通知を行えるようにする**
- **CIテストの設定：現在ローカルでPHPUnitテストを実行しているので、CircleCIを使用して自動化したい**
- **拡張子.HEICの画像ファイルアップロードをできるようにしたい**
- **フォローしている同士でチャットできる機能を実装したい**

## 15.最後に
今回のポートフォリオ作成を通して、バックエンド、フロントエンド、インフラの技術、役割、繋がりを学び、学習開始時と比べてかなり成長できたと感じましたが、
こうして記事にしてまとめ振り返ってみると、まだまだ学ぶべきことがあり過ぎるなと痛感しました。

私が実装したPHP/Laravelの機能はほんの基本部分で、まだまだやれることがたくさんあり、これからも新しく増え続けていくのだと考えると、気が遠くなる一方もっとできることを増やして、自由自在にコードを書けるよになりたいと楽しさを覚えました。

**コードを書いていてエラーに直面した時、何時間も調べて悩み、解決できたときの爽快感は最高です。**
日に日にエラー解決に費やす時間も短くなり、検索能力も上がってきて慌てず冷静に対処できるようにもなりました。
また、メンターの方のご助言もあり、様々な難問と向き合いながらポートフォリオを完成させた今、エンジニアとしてやっていける自信が身につきました。

これからも**毎日キャッチアップ**し**新しい事にも挑戦して**、**問題を解決し改善し続けるエンジニア**になります。

**最後までお読みいただき、ありがとうございました!!**


## 16.参考にした学習サービス・教材

### <font color="OrangeRed">独学エンジニア</font>
実務で自走できるエンジニアになることを目指すオンライン動画学習サービス
PHPの基礎、アプリ開発の基礎を学習できました。

PHP基礎
Docker/DockerCompose操作
Git/GitHub操作

https://dokugaku-engineer.com/

### <font color="RoyalBlue">やんばるエキスパート PHPコース</font>
PHP/Laravelの学習、共同開発の経験ができるサービス
PHP/Laravelを使用したアプリ開発、実務を想定した共同開発を経験できました。

現役エンジニアによるコードレビュー、MTG有り。
PHP/Laravelの基礎・応用
Docker構築
Git,GitHub操作
受講生同士で共同開発

https://www.yanbaru-code.com/php

### <font color="DarkTurquoise">MENTA</font>
安達 涼/adachin👾SREさんのメンタープランにてインフラ構築をサポートしていただきました。
インフラの構造や構築方法を学び、ポートフォリオのデプロイを行うことができました。

Docker構築
AWS構築
CircleCIを使用した自動デプロイ設定

https://menta.work/plan/442/5218

https://speakerdeck.com/rvirus0817/menta-sabaenziniajiao-yu-nituite?slide=22

 ### <font color="MediumBlue">TechPit</font>
ハンズオンでプログラミング学習ができる学習サービス
学習した教材一覧：

https://www.techpit.jp/courses/132

https://www.techpit.jp/courses/11

https://www.techpit.jp/courses/78

https://www.techpit.jp/courses/139

https://www.techpit.jp/courses/159

### <font color="Purple">Udemy</font>
ハンズオンで様々なジャンルの学習ができる動画学習サービス

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

https://www.udemy.com/course/html-css-js/

https://www.udemy.com/share/101Yby2@PW5gfWFTTFUOe0FHBktnfj5HYFc=/

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

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

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