Laravel5.7: Herokuにデプロイする

Laravelで作ったWebアプリを[Heroku](https://www.heroku.com/)にデプロイして公開します。
すでにHerokuでユーザー登録しているものとして話を進めます。

# 親記事
[Laravel 5.7で基本的なCRUDを作る - Qiita](https://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)


# Heroku CLIをインストールする
まずはPowerShellで`heroku`コマンドを使えるようにします。
Windowsの場合は下記からインストーラをダウンロードし、インストールます。
:link: [Windows | Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli#windows)

```text:PowerSehll
# Laravelのフォルダ直下へ移動する
> cd path\to\Laravel

# Herokuにログインする
> heroku login
```

:link: [Getting started | Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli#getting-started)


# Herokuアプリを新規作成し、同時にPHPを使用可能にする
```text:PowerShell
# Herokuアプリを新規作成する
> heroku create sutara79-laravel --buildpack heroku/php
```

:link: [Setting a buildpack on an application](https://devcenter.heroku.com/articles/buildpacks#setting-a-buildpack-on-an-application)


# Laravel側の設定
## Procfileを作る
[Procfile](https://devcenter.heroku.com/articles/procfile)はHerokuアプリの起動時に実行するプロセスを定義するためのファイルです。
今回は、サーバーにApacheを使うこと、`public/`をドキュメントルートとすることを宣言するために使います。
アプリフォルダ直下に`Procfile`を作ります。

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

:link: [Define a Procfile](https://devcenter.heroku.com/articles/getting-started-with-php#define-a-procfile)


## PHPの国際化用拡張モジュール(intl)を使う
HerokuではcURLやPDOなどのPHP拡張機能は自動で有効になります。
しかし、intlはComposerを通じて有効にしなければなりません。
:link: [Extensions](https://devcenter.heroku.com/articles/php-support#extensions)

その際のパッケージ名は、上のページの括弧内で示されている識別名に`ext-`という接頭辞を加えたものとなります。
また、バージョンは`*`を指定します。
:link: [Using optional extensions](https://devcenter.heroku.com/articles/php-support#using-optional-extensions)

つまり、下記のコマンドでOKです。

```text:PowerShell
> composer require ext-intl:*
```


## HTTPSを強制する
ログイン関連のページへのリンク作成に[ヘルパー関数のroute()](https://readouble.com/laravel/5.7/ja/helpers.html#method-route)を使っています。
[HTTPSを有効にしたXAMMP](https://qiita.com/sutara79/items/21a068494bc3a08a4803)のローカル環境では、リンクURLのスキームはきちんと`https`となります。
しかし、Herokuではなぜか`http`となってしまいます。
Herokuでは基本的にHTTPSは有効となっているはずなのに…。

`route()`には`url()`に対する`secure_url()`とは違い、HTTPSを強制するヘルパーは存在しません。
そこで、本番環境ではHTTPSを強制する処理を`AppServiceProvider`の`boot()`に記述します。
:link: [Laravel 5.2 - Forcing HTTPS Routes when using SSL - Jeff Mould](http://www.jeffmould.com/2016/01/31/laravel-5-2-forcing-https-routes-when-using-ssl/)

```php:app/Providers/AppServiceProvider.php
    public function boot()
    {
        // 本番環境(Heroku)でhttpsを強制する
        if (\App::environment('production')) {
            \URL::forceScheme('https');
        }
```

なお、このメソッド名はLaravel5.3以前は「forceSchem<b>a</b>」でしたが、5.4以降は「<a href="https://laravel.com/api/5.7/Illuminate/Routing/UrlGenerator.html#method_forceScheme" target="_blank">forceSchem<b>e</b></a>」です。
:link: [forceScheme or forceSchema in Laravel 5.4](https://laracasts.com/discuss/channels/laravel/forcescheme-or-forceschema-in-laravel-54)

## コミットする
ここまでの変更をコミットします。

```:PowerShell
> git add -A .
> git commit -m "Add Procfile"
```


# デプロイする
普通のGitコマンドです。

```txt:PowerShell
> git push heroku master

# ローカルのmasterブランチ以外をプッシュしたい場合 (例: ブランチ名 5.7)
> git push heroku 5.7:master
```

なお、GitHubへプッシュすると自動でHerokuにもデプロイする、ということもできます。
ダッシュボードの「Deploy」のページで、下記のようにGitHubリポジトリと連携させます。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/27816/637c1fdc-a21e-12ad-18fc-095222b2779d.png)

連携させた後も、`git push heroku master`で直接デプロイすることもできます。

# Heroku用の環境設定をする
:link: [Getting Started with Laravel on Heroku](https://devcenter.heroku.com/articles/getting-started-with-laravel)
:link: [HerokuでLaravel - Qiita](https://qiita.com/niiyz/items/07c07ebd7cd8993dc28e) [![hatena bookmark](http://b.hatena.ne.jp/entry/image/https://qiita.com/niiyz/items/07c07ebd7cd8993dc28e)](http://b.hatena.ne.jp/entry/https://qiita.com/niiyz/items/07c07ebd7cd8993dc28e)

下記の6つをまとめて設定します。

1. APP_NAMEを設定
2. APP_KEYを生成&設定
3. Debugbarを有効にする
4. 本番用のAPP_URLを設定
5. セッションはファイルに保存する
6. メール設定 (YahooのSMTPを利用)  
  :link: [Yahoo!メールのSMTP設定](https://www.yahoo-help.jp/app/answers/detail/p/565/a_id/47789/~/smtp-auth%E3%81%A8%E3%81%AF%EF%BC%88%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E8%AA%8D%E8%A8%BC%E8%A8%AD%E5%AE%9A%EF%BC%89)  
  平文で送らないとエラーになるので、`MAIL_PORT`は587番、`MAIL_ENCRYPTION`は空欄にします。

```text:PowerShell
> heroku config:set `
APP_NAME=demo-laravel-crud `
APP_KEY=$(php artisan key:generate --show) `
DEBUGBAR_ENABLED=true `
APP_URL=https://sutara79-laravel.herokuapp.com `
SESSION_DRIVER=file `
MAIL_DRIVER=smtp `
MAIL_HOST=smtp.mail.yahoo.co.jp `
MAIL_PORT=587 `
MAIL_USERNAME=<Yahooのユーザー名> `
MAIL_PASSWORD=<Yahooのパスワード> `
MAIL_ENCRYPTION= `
MAIL_FROM_ADDRESS=<Yahooのユーザー名>@yahoo.co.jp `
MAIL_FROM_NAME=demo-laravel-crud


# 現在の設定を確認する
> heroku config
```

# PostgreSQLを用意する
データベースの利用には、クレジットカード番号の登録が必要です。
ただし、無料プランならば料金は発生しません。
:link: [Heroku Postgres](https://devcenter.heroku.com/articles/heroku-postgresql)
:link: [Laravel5 HerokuでPostgreSqlを使う設定 - Qiita](https://qiita.com/mm36/items/a743a831fd5cd4324907) [![hatena bookmark](http://b.hatena.ne.jp/entry/image/https://qiita.com/mm36/items/a743a831fd5cd4324907)](http://b.hatena.ne.jp/entry/https://qiita.com/mm36/items/a743a831fd5cd4324907)

```txt:PowerShell
# 無料プランでDBを作成
> heroku addons:create heroku-postgresql:hobby-dev


# DB情報を確認
> heroku config:get DATABASE_URL
postgres://<ユーザ名>:<パスワード>@<ホスト>:5432/<DB名>


# LaravelのDB用に環境変数を設定
# (上記の結果を当てはめる)
> heroku config:set `
DB_CONNECTION=pgsql `
DB_HOST=<ホスト> `
DB_DATABASE=<DB名> `
DB_USERNAME=<ユーザ名> `
DB_PASSWORD=<パスワード>


# マイグレーションとシーディングを実行
> heroku run php artisan migrate --seed

# (マイグレーションをやり直したい場合)
> heroku run php artisan migrate:refresh --seed
```


マイグレーションとシーディングの際に「本番環境ですが、実行してもよろしいですか?」と聞かれるので「yes」と入力します。

```txt
**************************************
*     Application In Production!     *
**************************************

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

# 動作確認
`https://<アプリ名>.herokuapp.com/`にアクセスします。
または、Herokuのダッシュボードから`Open app`をクリックします。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/27816/f81e6b47-8f96-82ad-8674-6c7289030f82.png)

うまく表示されない場合はログを確認します。
ダッシュボードから、またはコマンドでログを表示できます。

```text:PowerShell
# アプリ「sutara79-laravel」の最新のログ5件を表示
> heroku logs -a sutara79-laravel -n 5
```

:link: [heroku logsのコマンド解説](https://devcenter.heroku.com/articles/heroku-cli-commands#logs)