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側のルーティングは初回のアクセスに対するもの

web.php
Route::get('/{any?}', function () {
    return view('index');
})->where('any', '.+');
④初回アクセス時のblade作成
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ファイルをもとにしたベースを紹介します

resources/js/views/Home.vue
<template>
  <div>Home</div>
</template>
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

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

Vue.use(Vuex)

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

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デプロイ時にビルドさせるためのスクリプト記述

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
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からアプリ作成に進む

②一意なアプリ名を入力してCreate App

何も入力しなかった場合は自動的にアプリ名が割り振られる

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

③Find more add-onsからMySQL作成に進む

④ClearDB MySQLを選択→install clearDB MySQL

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

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

⑥DBの接続情報確認

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

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

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

5. Heroku自動デプロイ設定

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

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

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

後は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を変更する

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'),
            ]) : [],
        ],