【Laravel / Vue / Docker / AWS / CircleCI】実務未経験がポートフォリオとして独学WEBアプリ開発

# 0. はじめに
大阪のLaravel初学者のkazumakishimoto([@kazuma_dev](https://twitter.com/kazuma_dev))です！
```
・実務未経験から半年独学で、Laravel/Vue/AWS/Docker/CircleCIのWEBアプリ開発
・大阪でバックエンドエンジニア転職活動中(22/07)
```

## 0-1. 全体の流れ
> [1.アプリ概要](#1-アプリ概要)
> [2.使用技術](#2-使用技術)
> [3.機能一覧](#3-機能一覧)
> [4.基本設計](#4-基本設計)
> [5.難点](#5-難点)
> [6.意識](#6-意識)
> [7.課題](#7-課題)
> [8.作者](#8-作者)
> [9.教材](#9-教材)

# 1. アプリ概要
|key|value|
|:--|:--|
|Name|飲食店とインフルエンサーのマッチングアプリ`grfl`|
|URL①|https://grfl.work/|
|URL②|https://grfl.herokuapp.com/|
|GitHub|https://github.com/kazumakishimoto/grfl|
|Qiita|https://qiita.com/kazumakishimoto/items/2ac669119c968e30ae37|

![top](https://user-images.githubusercontent.com/68370181/202880273-db7d6990-18c5-43c5-91c2-41c09fb5b264.png)

## 1-1. コンセプト
- 安価で簡単にSNS広告を始められるWEBアプリケーション
- 飲食店：広告依頼を投稿することで、インフルエンサーにSNS広告の募集ができる
- インフルエンサー：投稿一覧から自分に合った広告案件を発見できる

## 1-2. 特徴
- 飲食店のSNS広告内容の投稿機能・画像アップロード機能
- 都道府県・カテゴリー別の投稿検索機能・ソート機能
- ダイレクトメッセージ機能(作成中)

## 1-3. 開発目的
1. `Laravel/Vue.js/AWS/Docker/CircleCI`の学習のため
2. 流行病によって家族や友人が経営破綻したことから、「WEBサービスの力で中小企業やスタートアップ企業を支援したい」と思ったため

## 1-4. 使用画面のイメージ
![demo](https://user-images.githubusercontent.com/68370181/169194020-4e4f251c-2ec2-4934-bbe7-c815829d2dcf.png)


# 2. 使用技術
## 2-1. ディレクトリ構造
```
【ルートディレクトリ】
├─ .circleci
│   └─ config.yml
├─ aws / CloudFormation
│   └─ ec2.yml
├─ docker
│   └─ mysql
│   └─ nginx
│   └─ php
│   └─ phpmyadmin
├─ src
│   └─ 【Laravelのパッケージ】
└─ docker-compose.yml
```

## 2-2. フロントエンド
- Vue.js 2.6.14
- jQuery 3.4.1
- HTML/CSS/Sass/Bootstrap

## 2-3. バックエンド
- PHP 7.4.1
- Laravel 6.20.43
- PHPUnit 8.0

## 2-4. DB
- MySQL 5.7.36
- PHPMyAdmin
- PostgreSQL(Heroku)

## 2-5. 開発環境
- GitHub
- Git-flow
- Docker
- VScode
- MacOS

## 2-6. 本番環境
- AWS(CloudFormation/VPC/EC2/RDS/S3/Route53/ALB/ACM/CodeDeploy/SNS/Chatbot/IAM/CloudWatch)
- Heroku
- CircleCI
- Nginx

## 2-7. パッケージ管理
- Composer
- npm

## 2-8. その他使用ツール
- draw.io
- SendGrid
- Notion


# 3. 機能一覧
## 3-1.メイン機能
- ユーザー投稿機能(CRUD)
- 画像アップロード機能(AWS S3)
- ページネーション機能
- コメント機能(CRUD)
- タグ機能(Vue.js)
- いいね機能(Vue.js/Ajax)
- フォロー機能(Vue.js/Ajax)
- キーワード検索機能(都道府県別ソート機能)
- お問い合わせ機能(SendGrid)
- PHPUnitテスト(CircleCI)
- レスポンシブWEBデザイン

## 3-2. 認証機能
- 会員登録/ログイン/ログアウト
- ゲストログイン機能
- Google会員登録/ログイン(GCP OAuth)
- Twitter会員登録/ログイン(Twitter OAuth)
- プロフィール編集
- メールアドレス変更(SendGrid)
- パスワード再設定(SendGrid)
- 退会

## 3-3. インフラ
- CloudFormationで環境構築(VPC/EC2)
- RDS(MySQL)
- ACM/ELBでHTTPS化
- CircleCI/CodeDeployで自動デプロイ
- SNS/ChatbotでSlackデプロイ通知


# 4. 基本設計
## 4-1. インセプションデッキ
- ※作成中

## 4-2. 画面遷移図
![gui](https://user-images.githubusercontent.com/68370181/160355552-328990f2-bc02-4607-9a90-32a48eff4a85.png)

## 4-3. 開発環境
- 開発環境：`Docker/docker-compose`
- バージョン管理：`GitHub/Git-Flow`
- 開発ツール：`VScode/MacOS`

|key|value|
|:--|:--|
|php|app|
|nginx|web|
|mysql|db|
|phpmyadmin|db管理|

## 4-4. 本番環境
- IaC：`CloudFormation`
- CI/CD：`CircleCI/CodeDeploy`
- 本番環境：`Subnet/Route53/ALB/ACM/S3`

![aws](https://user-images.githubusercontent.com/68370181/178103075-eec5508a-4d29-409c-84f4-3f687fa9cd5d.png)

|key|value|
|:--|:--|
|CloudFormation|環境構築|
|VPC|サブネット(EC2 / RDS)|
|EC2|nginx / php-fpm(public subnet 1a,1c)|
|RDS|MySQL(private subnet 1a,1c)|
|S3|画像用ストレージ|
|Route53|DNSレコード管理|
|ALB|ロードバランサー|
|ACM|SSL証明書取得(HTTPS化)|
|SNS|Slackデプロイ通知|
|Chatbot|Slackデプロイ通知|
|CircleCI|自動デプロイ|
|CodeDeploy|自動デプロイ|
|IAM|権限付与|
|CloudWatch|料金確認|

## 4-5. ER図
![erd](https://user-images.githubusercontent.com/68370181/163666380-247d7cb3-3e61-4fdb-98fb-4f16d16aa59c.png)

## 4-6. テーブル定義書
| tables | desc |
|----|----|
| Users | ユーザー情報 |
| Articles | ユーザー投稿情報 |
| Tags | ユーザー投稿のタグ情報 |
| Article_tags | ArticlesとTagsの中間テーブル |
| Likes | ユーザー投稿のいいね情報 |
| Comments | ユーザー投稿のコメント情報 |
| Follows | フォロー中/フォロワーのユーザー情報 |
| Messages | ユーザー間のダイレクトメッセージ情報 |
| Rooms | ダイレクトメッセージのルーム情報 |
| Entries | MessagesとRoomsの中間テーブル |

https://docs.google.com/spreadsheets/d/1R7VARnAYGivhzmraesTzjtEwzi4NCR7UnvDdrqGi9NU/edit?usp=sharing

## 4-7. issue
https://github.com/kazumakishimoto/grfl/issues

## 4-8. Git-Flow
https://qiita.com/mint__/items/bfc58589b5b1e0a1856a

## 4-9. 開発期間
- 要件定義から約半年間
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687994/d49b9d32-45ce-bd77-e658-017793bdce67.png)


# 5. 困難だったこと
## 5-1. 基本設計
- 機能一覧から画面遷移図/テーブル定義書/ER図を作成
- ER図・AWS構成図をdraw.ioで作成
- issue/PR/コミットメッセージの、書き方を統一しておくべきだった

## 5-2. Laravel
- ソーシャルログイン機能(Twitter OAuth)
- 画像アップロード(AWS S3)
- 検索機能(強制HTTPS化)

https://qiita.com/kazumakishimoto/items/d08c7ea9dc25cf06bb65

https://qiita.com/kazumakishimoto/items/7ea70c552a78ab73074f

https://qiita.com/kazumakishimoto/items/7574baa76e87a5312e3c

## 5-3. CI/CD
- config.ymlの書き方

https://qiita.com/kazumakishimoto/items/6aac32725ebea25acf35

## 5-4. AWS
### EC2
- php-fpmやNginxのファイル設定
- Linuxユーザー権限
- EC2上のLaravelやNginxのエラーログ理解

### ALB/ACM
- Laravel側のHTTPS化設定

### CircleCI/CodeDeploy
- サブディレクトリのデプロイ設定(config.ymlのworking_directory設定)
- permissionエラー(.circleciディレクトリの権限)
- ヘルスチェックエラー(ターゲットグループの設定)

### SNS/Chatbot
- Chatbotに`ServiceLinkedRole`のインラインポリシー作成


# 6. 意識したこと
## 6-1. セキュリティ
- `.env.testing`や`.env.example`にベタ書きしない
- `.gitignore`に`.env`を必ず記載
- configでは環境変数で呼び出し

```php:config/services.php
<?php

return [

    //略

    'ses' => [
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],

    'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect' => env('APP_URL') . '/login/google/callback',
    ],
];
```

https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-access-keys-best-practices.html


# 7. 課題
- ユーザー検索機能
- DM機能
- 通知機能
- SNSシェア機能
- マルチログイン機能


# 8. 作者
|key|value|
|---|-----|
|名前|岸本一眞(きしもとかずま)|
|住所|大阪市|
|ポートフォリオ|[**grfl.work**](https://grfl.work)|
|GitHub|[@kazumakishimoto](https://github.com/kazumakishimoto)|
|Qiita|[@kazumakishimoto](https://qiita.com/kazumakishimoto)|
|Twitter|[@kazuma_dev](https://twitter.com/kazuma_dev)|


# 9. 教材
## 9-1. 基本設計
https://twitter.com/masakichi_eng/status/1398474289536409601?s=21

https://yutaro-blog.net/2021/07/25/programming-loadmap-3/

https://yutaro-blog.net/2021/05/22/laravel-recommend/

https://note.com/poly_soft/n/n5b1d72539ed2

https://note.com/techpit/n/na742e7de3f4e

https://qiita.com/newta/items/f4aff8cdd8706d5d08c5

https://qiita.com/newta/items/4dfbd7ecf86ef74e70dd

## 9-2. Git
https://www.udemy.com/course/unscared_git/

https://backlog.com/ja/git-tutorial/

https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0

## 9-3. PHP
https://dotinstall.com/lessons/basic_php_v3

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

https://www.udemy.com/course/php-master/

https://amazon.co.jp/dp/4798168491

## 9-4. JavaScript
https://amazon.co.jp/dp/B09HC854HS

## 9-5. SQL
https://www.amazon.co.jp/dp/4295005096

https://www.amazon.co.jp/dp/B00EE1XPAI

## 9-6. CS
https://www.amazon.co.jp/dp/4297117819

## 9-7. Linux
https://www.udemy.com/course/unscared_linux/

https://linuc.org/textbooks/linux/

## 9-8. Laravel
https://youtube.com/playlist?list=PLh6V6_7fbbo8bb7eajaLdsQZ9fLhMJ-oc

https://youtube.com/playlist?list=PLCyDm9NTxdhLnA4tH5ToQR1K1LcWIAdOa

https://dotinstall.com/lessons/basic_laravel_v3

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

https://www.amazon.co.jp/dp/B07CLLW4MX

https://qiita.com/shonansurvivors/items/43b4480a84921d185e34

https://qiita.com/namizatork/items/d79017aa474966244073

https://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea

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

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

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

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

## 9-9. Docker
https://amazon.co.jp/dp/B08T961HKP

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

https://yutaro-blog.net/2021/04/28/docker-laravel-vuejs-1/

https://yutaro-blog.net/2021/05/25/docker-laravel-vuejs-m1/

https://qiita.com/furu8ma/items/50718efebee20fd24517

https://qiita.com/kazumakishimoto/items/1895866a4924c9cdaba4

## 9-10. AWS
https://www.udemy.com/course/aws-for-beginner/

https://www.udemy.com/course/aws-and-infra/

https://www.amazon.co.jp/dp/4296105442

## 9-11. CircleCI
https://www.techpit.jp/courses/78

https://www.amazon.co.jp/dp/4297114119

## 9-12. 基本設計
https://qiita.com/ryamate/items/5446620c6d16ddbdd02f

https://qiita.com/Saku731/items/741fcf0f40dd989ee4f8

https://qiita.com/Yakushigawa_N/items/7c2e00f514dc9c44c3e0

https://qiita.com/tanksuzuki/items/7bdf9e1f003b98b01271

https://qiita.com/yait/items/ef41a2a6677a88c639da

https://it-koala.com/entity-relationship-diagram-1897

https://qiita.com/yagi_eng/items/fac0e257317cea32d2d1

https://qiita.com/ramuneru/items/db43589551dd0c00fef9

https://qiita.com/ramuneru/items/32fbf3032b625f71b69d

https://qiita.com/riku-shiru/items/5ab7c5aecdfea323ec4e

https://qiita.com/G-awa/items/8fd414700b68b2bcafcc

https://qiita.com/nisj/items/948f05f93dce4628fda5

https://qiita.com/KosukeSone/items/514dd24828b485c69a05

https://qiita.com/yuki0410_/items/7c7fa20710dfd72b7d7a

https://qiita.com/tanishi/items/09e72c65c0a0c9e1cc10

https://qiita.com/fukubaka0825/items/c7710b4e87d478c8ba3b

https://qiita.com/tkmd35/items/9612c03dc60b1c516969

## 9-13. 参考ポートフォリオ
https://qiita.com/shimotaroo/items/409e77dfb121dd40ac1d

https://qiita.com/nasuB7373/items/0e507abad2017976c407

https://qiita.com/ryamate/items/c3b4f63f8d94ab090bf8

https://qiita.com/NULL_000000/items/b5c06cca2dd17e4dd00b

https://qiita.com/yuuichimizuta/items/e8a8cf2bbecba7cba965

https://qiita.com/Yuhei_K/items/06805f3ac8607f77952f