LoginSignup
8
12

More than 1 year has passed since last update.

Dockerで構築した環境を基に、Herokuへデプロイする(Nginx, Laravel,VueJS,PostgresSQL)

Last updated at Posted at 2021-11-21

目的

Dockerで構築したローカルの開発環境を基に、
アプリケーションをHerokuへデプロイしたい。

Herokuの機能を使用して、
GitHubのリモートリポジトリへPushしたら自動でHerokuのデプロイが走るようにしたい。

参考

上記の記事を参考にいたしました。

環境

以下の環境をDockerを使ってローカル上に構築しています。

サービス 名前 バージョン
Webサーバー nginx 1.15.6
フロントエンドFW VueJS vue@2.6.14
バックエンドFW Laravel 7.30.5 (php:7.2-fpm)
データベース PostgreSQL latest(psql (PostgreSQL) 14.1 (Debian 14.1-1.pgdg110+1))]
データベースGUI PG Admin 4

事前準備

・Herokuへの登録
・Heroku CLIのインストール
・GitHubへの登録

設定ファイル

に今回使用する設定ファイルを置いています。

開発環境構築(Nginx, Laravel, PostgresSQL)

powershell
git clone https://github.com/roughstorm/dnlvp
cd dnlvp
docker-compose up --build -d
docker-compose exec app bash

リポジトリからクローンした設定ファイルを基にDocker-composeでDocker上に環境構築し、appコンテナ内に入る。

上記の設定ファイルを使用する場合は、以下の事項に注意してください。 ローカルでのDockerコマンド実行前に、`docker-compose.yml`内の`pgadmin`の`environment`の`PGADMIN_DEFAULT_EMAIL`のメールアドレスを適宜変更してください。 `docker/web/default.conf`内にてrootを`root /var/www/html/[dnlvp]/public;`と指定しています。 作成するLaravelのプロジェクト名(フォルダ名)に合わせて[dnlvp]の部分を変更してください。

app
composer create-project --prefer-dist laravel/laravel dnlvp
cd dnlvp/
chmod -R 777 storage

composerコマンドで新しいLaravelプロジェクトを作成し、
storageフォルダに権限を付与(log出力のエラーが出るため)

.env
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=sample
DB_USERNAME=user
DB_PASSWORD=password

Laravelプロジェクト作成時にできる環境設定ファイル(.env)にPostgresSQL用の環境変数をセットする。

app
php artisan migrate

php artisan migrateで、DBのマイグレーションを行っておく。

VueJSのインストール

app
composer require laravel/ui
php artisan ui vue
npm install
npm install -D vue
npm install --save vue-router
npm list vue
npm run dev
npm audit fix
npm run watch

composer require laravel/uiのコマンドでLaravelでVue(Reactも)を使うためのライブラリをインストールします。
php artisan ui vueコマンドでvue用のスカフォールドを設定します。

npmコマンドnodejsのコマンドです。
npm installコマンドについては、下記のサイトが参考になりました。

npm list vueコマンドで、バージョンが返ってくればvueがインストールされています。

npm run watchコマンドまで実行したら、動作を確認します。

ローカルでの動作確認

まず、動作確認用に以下のファイルを編集/作成します。
dnlvp/routes/web.php
dnlvp/resouces/views/app.blade.php

dnlvp/routes/web.php
<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/{any}', function() {
    return view('app');
})->where('any', '.*');
dnlvp/resouces/views/app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Vue Laravel SPA') }}</title>

    <!-- Styles -->
    <link href="{{ mix('/css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
<example-component></example-component>
</div>
<!-- Scripts -->
<script src="{{ mix('/js/app.js') }}" defer></script>
</body>
</html>

上記のファイルを更新/作成した状態で、localhost:8000にアクセスし、以下の画面のように動作が確認できると思います。

image.png

.gitignoreの設定

コンパイル済みファイルである、/public/js/public/cssはgit管理する必要がないのでgitignoreに追記しておきます。
これらのファイルは、Herokuではデプロイ時にまた作成されるようです。

.gitignore
/public/js
/public/css

Herokuへのデプロイ

下記コマンドを実行する前に、カレントディレクトリをLaravelのプロジェクトフォルダに移動しておいてください。

Herokuアプリの作成

powershell
heroku login
heroku create dnlvp

heroku loginでHerokuにログインします。ブラウザが開いて認証します。
heroku createで新しいHerokuアプリを作成します。 dnlvpがアプリ名になります。既に同じ名前のアプリがあると作成できません。(testとかはすでにとられてます。)

GitHubリポジトリの準備

今回は、Herokuの機能を使用して、GitHub上のリモートリポジトリにPushしたらHerokuにもデプロイが走るようにしたいので、まずGitHubにHerokuアプリ用のリポジトリを作成します。

今回は、https://github.com/roughstorm/dnlvponheroku.gitというリポジトリを作成しました。

HerokuとGitHubで連携をする場合は、リポジトリが空だと連携出来ないと表示されるので、まず先にリポジトリ内にファイルをいれます。

echo "It's a practice for deploy on Heroku." >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/roughstorm/dnlvponheroku.git
git push -u origin main

これらのコマンドは、カレントディレクトリをLaravelのプロジェクトフォルダに移動してから実行してください。(.envなどがあるフォルダ)

HerokuとGitHubを連携させて自動デプロイの設定

image.png
https://jp.heroku.com にログインし、作成したプロジェクトを選びます。

image.png
Deployをクリックします。

image.png
Deployment methodでGitHubを選択します。

image.png
Github上のリポジトリを検索するテキストボックスが出るので、自身の設定したリポジトリ名を検索して、適用したいリポジトリを選んでConnectを押します。

image.png
まだこの状態ではPushしただけで自動でデプロイが走るようにはなっていません。
HerokuとリポジトリのConnectが完了すると、Automatic deploysという項目ができて、Enable Automatic Deploysというボタンが出ますので、こちらを押すことによって自動デプロイの設定が完了します。

Heroku側のBuildpacks(PHPとNodeJS)の設定

Heroku側での設定をしていきます。
なお、下記Herokuコマンドは -a で自身のアプリ名を指定しないと動きません。

powershell
heroku buildpacks:set heroku/php -a dnlvp
heroku buildpacks:add heroku/nodejs -a dnlvp

buildpacks(アプリがデプロイされる際に実行されるスクリプト)の設定をします。
LaravelとVueを使うので、phpとnodejsをセットします。

image.png
ちなみに、 上画像のように https://jp.heroku.com 
にログインし、アプリを選択した後、Settingsのタブからもbuildpacksの設定、確認を行うことができます。

Heroku側のPostgresSQLの設定

powershell
heroku addons:create heroku-postgresql:hobby-dev -a dnlvp

addonにPostgresSQLを追加します。

image.png
こちらも、https://jp.heroku.com
からログインし、アプリを選択した後、Resourcesのタブから設定や確認ができます。

powershell
heroku config:get DATABASE_URL -a dnlvp

addonにPostgreSQLを追加すると、自動で環境変数にDATABASE_URLが追加されるので、そちらを取得し、Herokuへ設定していきます。
heroku config:get DATABASE_URLを実行すると、以下の形式で返ってきますので、これらを基に対応する値をHerokuへ設定していきます。
postgres://<ユーザ名>:<パスワード>@<ホスト>:5432/

powershell
heroku config:set DB_CONNECTION=pgsql -a dnlvp
heroku config:set DB_HOST=<ホスト> -a dnlvp
heroku config:set DB_DATABASE=<DB名> -a dnlvp
heroku config:set DB_USERNAME=<ユーザ名> -a dnlvp
heroku config:set DB_PASSWORD=<パスワード> -a dnlvp

image.png

image.png

こちらも、https://jp.heroku.com
からログインし、アプリを選択した後、SettingsのタブのConfig Varsから設定や確認ができます。

Laravelの環境変数の設定

powershell
heroku config:set APP_ENV=production -a dnlvp
heroku config:set APP_DEBUG=false -a dnlvp
heroku config:set APP_URL=https://dnlvp.herokuapp.com/ -a dnlvp

Laravelで使用するAPP_ENVなどの環境変数を設定します。
APP_URL=https://dnlvp.herokuapp.com/については、自身のアプリのURLを指定してください。

Procfile, nginx.confの追加#

Laravelプロジェクトのフォルダに、下記のファイルを新規作成します。
Procfile
nginx.conf

Procfile
web: vendor/bin/heroku-php-nginx -C nginx.conf public/

Procfileはアプリケーションがどのプロセスを使うのか宣言するためのファイルだそうです。

web: vendor/bin/heroku-php-nginx によってnginxを使用することを指定し、
-C nginx.conf で、同じフォルダ内にある nginx.confファイルを参照することを指定、
public/ でドキュメントルートの指定をしています。

また、Procfileはファイル名が決まっているので大文字(PROCFILE)とか小文字(procfile)だと動きませんでした。

nginx.conf
location / {
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /index.php$1 last;
}

location / {~ ~}にて、アクセスしたURLのファイルがあるかどうかを確認し、あればそのファイルを返し、なければ@rewriteappロケーションに行きます。

location @rewriteapp{~ ~}にて、送られてきたURI応じて、index.php[正規表現に一致する部部分]として書き換え、lastがあるので、location / {~ ~}の処理から、また一致するかどうかを確認していく、と思います。

今回デプロイするHerokuのアプリでは、アプリのURLにアクセスすると,Procfileに設定したpublic/へ行き、nginx.confの処理によってpublic/index.phpが戻ってくることによって、アプリへアクセスが出来るということになると思います。

下記の記事を参考にいたしました。

package.json, composer.jsonの編集

下記のファイルを編集します。
package.json
composer.json

package.json
 "heroku-postbuild": "npm run prod"

package.json内の"scripts"要素の中に、"heroku-postbuild": "npm run prod"を追加します。
これをいれないと、Heroku上でnpm run buildがされないので、vueが使えません。

"scripts"要素内に追加する際に、最後の行に入れる場合は、上行の改行の前に,を入れないと、ファイルを読んだ際にエラーが出ます。

composer.json
    "require": {
        "php": "^7.2.5|^8.0",
        "ext-intl": "*",
        "fideloper/proxy": "^4.4",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "^6.3.1|^7.0.1",
        "laravel/framework": "^7.29",
        "laravel/tinker": "^2.5",
        "laravel/ui": "^2.5"
    },

composer.json内のrequire要素内に"ext-intl": "*",を追加します。
intl(国際化用拡張モジュール)を使用できるようにする為に必要です。
PHPで国際化用に使うライブラリの様です。
これらが具体的にどんな動作をするのかまではまだわかっていません・・すいません。

https強制化

こちらの記事を参考にいたしました。

app/Providers/AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        // 本番環境(Heroku)でhttpsを強制する
        if (\App::environment('production')) {
            \URL::forceScheme('https');
        }
    }
}

まず、ローカル環境のapp/Providers/AppServiceProvider.phpを上記の様に変更します。

powershell
docker-compose exec app bash
cd dnlvp/
php artisan make:middleware ForceHttpToHttps

Laravelのミドルウェアを作るため、コンテナ内に入り、
Laravelプロジェクトのフォルダでphp artisan make:middleware ForceHttpToHttpsを実行します。

app/Http/Middleware/ForceHttpToHttps.php
<?php

namespace App\Http\Middleware;

use Closure;

class ForceHttpToHttps
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (\App::environment(['staging', 'production']) && $_SERVER["HTTP_X_FORWARDED_PROTO"] != 'https') {
            return redirect()->secure($request->getRequestUri());
        }
        return $next($request);
    }
}

php artisan make:Middlewareで自動的にForceHttpToHttps.phpが作成されますので、
app/Http/Middleware/ForceHttpToHttps.phpを上記の様に書き換えます。

app/Http/Middleware/Kernel.php
(省略)
protected $middleware = [
(省略) 
     \App\Http\Middleware\ForceHttpToHttps::class, // 追加
    ];
(省略)

app/Http/Middleware/Kernel.phpに上記を追加します。

また、これらの変更を加えた時点でローカル環境に異常が発生していないか確認をしたほうがよいと思います。

デプロイ

powershell
git add .
git commit -m "initial commit"
git branch -M main
git push -u origin main

Laravelプロジェクトのフォルダで一度、上記を実行します。

これで一度Heroku上でデプロイが走ると思いますが、
設定していない項目がありますので、まだアプリは動きません。

APP_KEYの設定

powershell
heroku run php artisan key:generate --show -a dnlvp
heroku config:set APP_KEY='{ここに上記で生成されたAPP_KEY(base64から始まる文字列)をコピペ}' -a dnlvp

上記コマンドでAPP_KEYの設定をします。
APP_KEY=$(php artisan key:generate --show)で設定している記事を多くみかけましたが、私の環境からだと何度やってもAPP_KEYに空が設定されてしまうので、この様にしております。

DBのマイグレーション・シーディング

powershell
heroku run php artisan migrate --seed -a dnlvp

上記を実行します。

powershell
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 >

既にアプリケーションが動いている状態ですので、ほんとにマイグレーションしていいの?と聞かれますので、Yesでマイグレーションを実行します。

動作確認

image.png
自身のアプリのURLにアクセスし、動作を確認します。
Heroku上に構築された環境で、Vueのコンポーネントが表示されました。

おわりに

突貫な感じで恐縮ですが、開発から本番までの環境を作ることができてよかったです。

技術から別の技術へいろいろと派生していき、これを調べたらあれも調べないと、
みたいな感じで調査に時間がかかってしまうので、勉強不足を痛感しました。

技術的に拙い部分が多くあって怖いですが、
とりあえず環境ができたので実装のほうをやっていきたいと思っています。

内容について、やってはいけない感じのことをやっていたり、
こうしたほうがよいなどのご助言がありましたら、お教え頂けますと幸いです。

追記2021/11/23

私の環境だとこれで構築したDocker内の環境では、
npm run watch, npm run watch -pollともになぜか正常に動作しません。
ファイルの変更をキャッチして勝手にビルドしてくれないのです。なぜだい。

たぶん、webpack.mix.jsあたりに何かありそうな気がするんですが、頭が働いてくれませんでした。
なので、jsやvueを変えたら都度npm run devしてください。悲しみ。

8
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
12