Laravel+Vue+MySQL+GitHubでHerokuに自動デプロイ！ プロジェクト作成〜自動デプロイまで

## 概要

Laravelのプロジェクト作成しVueを導入する (リポジトリは分離させないのでVueCLI未使用)
GitHubのmasterブランチにPush/MergeされたらHerokuに自動デプロイさせる
データベースにはMySQLを使用
デプロイはCircleCI等のCIサービスは使用せずにHerokuのみで完結させる

## 開発環境

- Laravel 7.30.4
- Vue 2.6.12
- MySQL

## 目次
1. Laravelプロジェクト作成Git設定
2. Vue関連インストール&設定
3. Laravel側のHeroku設定
4. Herokuアプリ, MySQL作成
5. Heroku自動デプロイ設定


##1. Laravelプロジェクト作成&Git設定

##### ①GitHubのリモートリポジトリ作成

##### ②Laravelプロジェクト作成

```
composer create-project --prefer-dist laravel/laravel blog "7.*"
```

##### ③ルーティング設定

Vue-RouterでSPAにするので下記のLaravel側のルーティングは初回のアクセスに対するもの

```php:web.php
Route::get('/{any?}', function () {
    return view('index');
})->where('any', '.+');
```

##### ④初回アクセス時のblade作成

```html:views/index.blade.php
<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ config('app.name') }}</title>
    <!-- Scripts -->
    <script src="{{ mix('js/app.js') }}" defer></script>
    <!-- CSS -->
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>

<body>
    <div id="app">
        <router-view></router-view>
    </div>
</body>

</html>
```



### 下記のGit設定は必要に応じて行ってください

##### ⑤Git初期化＆リモートリポジトリ設定

```
git init

git remote add origin https://github.com/*********/*********.git
```

##### ⑥masterブランチにFirstCommit

```
git add .
git commit -m "first commit"
git push origin master
```

##### ⑦developブランチ作成＆リモートリポジトリにプッシュ

```
git checkout -b develop
git push origin develop
```

これでGit関連の基本的な設定終了

##2. Vue関連インストール&設定

##### ①Vueインストール

```
composer require laravel/ui "2.*"
php artisan ui vue
```

※laravel7の場合2.*が対応しているバージョン

##### ②Vue-Routerインストール

```
npm install vue-router
```

#####  ※必要に応じて ③Vuex, Vuetify, mdi/fontインストール

```
npm install vuex
npm install Vuetify
npm install @mdi/font
```

##### ④Home.vue, Router, Storeファイル作成 & インポート

 VueCLIで作成したわけではないのでrouterやstoreファイルを0から作成しなければなりません
下記はVueCLIで自動生成されるrouter,storeファイルをもとにしたベースを紹介します

```vue:resources/js/views/Home.vue
<template>
  <div>Home</div>
</template>
```


```js:router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
    {
        path: '/',
        name: 'Home',
        component: Home
    },
]

const router = new VueRouter({
    mode: 'history',
    routes
})

export default router

```

```js:store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

```

```js:app.js
import router from './router'
import store from './store'

window.Vue = require('vue');

const app = new Vue({
    router,
    store,
    el: '#app',
});
```

##3. Laravel側のHeroku設定


##### ①Procfile作成

プロジェクトルートにHerokuアプリ起動時に実行されるコマンド及びプロセスの種類を定義するファイルを作成します

```:Procfile
web: vendor/bin/heroku-php-apache2 public
```



##### ②package.json修正

Herokuデプロイ時にビルドさせるためのスクリプト記述

```diff:package.json
  "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js",
+       "postinstall": "npm run prod"
    },
```

##### ③Heroku用.envファイル作成

.envはデフォルトでgitの管理対象外なので本番環境用の.envを新規作成します
※デプロイ時には.envとして動かします

```
cp .env .env.heroku
```


```diff:composer.json
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ],
+        "compile": [
+           "@php -r \"file_exists('.env') || copy('.env.heroku', '.env');\""
+       ]
    }
```

##4. Herokuアプリ, MySQL作成

##### ①Create new appからアプリ作成に進む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/d4ac3da4-2f60-0c22-21e7-f42f8f51920a.png)

##### ②一意なアプリ名を入力してCreate App
何も入力しなかった場合は自動的にアプリ名が割り振られる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/7ac4a964-966f-1383-f030-cf73348b2330.png)

これでアプリは作成はできたがdyno(コンテナ)は作成されていない状態となる
Laravelのプロジェクトをデプロイしたらdynoが作られる

##### ③Find more add-onsからMySQL作成に進む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/8a24c96f-c579-65fd-408c-5ea99564797c.png)

##### ④ClearDB MySQLを選択→install clearDB MySQL

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/28dfc654-4647-e8df-fbc8-b23f385c817e.png)

##### ⑤App to provision toにはアプリ名を入力しSubmit Order Form

※ここでエラーが発生した場合はAccountSettings->Billingからクレジットカードを登録しているか確認
 PostgreSQLもMySQLも無料で使用できるがMySQLの場合はクレジットカード登録が必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/33eaf354-8791-ad20-3691-1064561a1db2.png)


##### ⑥DBの接続情報確認

Reveal Config Varsを選択するとCLEARDB_DATABASE_URLの値が表示されます
そこの値にはホスト名、ユーザー名、パスワード、DB名全てが記述されています
下記の書式を参考に各情報をひかえましょう

```
mysql://ユーザー:パスワード@ホスト/DB名?reconnect=true
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/21f9f097-18dd-acc5-9d23-4c6dfd3ff443.png)


#### ※Laravel側の.env.herokuにもDB情報を記述をしましょう


##5. Heroku自動デプロイ設定

##### ①Deployment method項目のGitHubアイコンボタンを選択

デプロイの資材となるリモートリポジトリを選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/152f1800-1240-a789-b1ba-04cf09d31eb2.png)

##### ②Enable Automatic Deploysで自動デプロイ設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/59fb2149-f415-a0e4-419b-88cced7b986e.png)


##### 後はGitHubのmasterブランチにプッシュorマージすると自動デプロイされます

## おまけ php artisan migrateする

```
heroku run php artisan migrate --app=アプリ名
```

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long
上記エラーが出た際はcharasetを変更する

```diff:config/database.php
  'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
-           'charset' => 'utf8mb4',
-           'collation' => 'utf8mb4_unicode_ci',
+           'charset' => 'utf8',
+           'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

```

https://qiita.com/beer_geek/items/6e4264db142745ea666f