LaravelプロジェクトをHerokuにデプロイする手順


LaravelプロジェクトをHerokuにデプロイする手順です。
データベースは、Heroku Postgresアドインを追加して設定します。

Qiitaなどに同様の記事はたくさんあがっていますが、改めて見返すと結構よくまとまっているので公開することにしました。

前提条件

  • composer
  • Heroku CLI

Heroku CLIのセットアップ

Heroku CLIはHomebrewでインストール可能です。

以下のコマンドでインストール

$ brew tap heroku/brew && brew install heroku
...
==> heroku
To use the Heroku CLI's autocomplete --
  Via homebrew's shell completion:
    1) Follow homebrew's install instructions https://docs.brew.sh/Shell-Completion
        NOTE: For zsh, as the instructions mention, be sure compinit is autoloaded
              and called, either explicitly or via a framework like oh-my-zsh.
    2) Then run
      $ heroku autocomplete --refresh-cache

  OR

  Use our standalone setup:
    1) Run and follow the install steps:
      $ heroku autocomplete

Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions

参考: The Heroku CLI | Heroku Dev Center

heroku login

Heroku CLIをインストールしたらheroku loginコマンドでCLIからherokuへのアクセスを許可します。

$ heroku login
heroku: Press any key to open up the browser to login or q to exit: 
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/a58a9741-e591-4620-bdf9-5a0f300ab95b
heroku: Waiting for login... ⣟

ブラウザにHeorkuへのログイン画面が表示されます

Heroku CLI login

[Login In]をクリック

Herokuアカウントでログインします

Heroku CLI logged in

ログインするとターミナルでは以下のように表示されます

Logging in... done
Logged in as hrendoh@gmail.com

Herokuへのデプロイ

Herokuにアプリケーションを作成して、Laravelプロジェクトをデプロイします。

Procfileの準備

Procfileを作成します。

Procfileとは、ドキュメントの以下の説明によると、Heorkuアプリケーションが起動される際に読み込まれ実行されるコマンドを記述するファイルで、起動するプロセスの種類などを指定できます。

Heroku apps include a Procfile that specifies the commands that are executed by the app on startup. You can use a Procfile to declare a variety of process types, including:

Laravelプロジェクトのルートディレクトリで以下のコマンドを実行しProcfileを作成、コミットしておきます。

$ echo "web: vendor/bin/heroku-php-apache2 public/" > Procfile
$ git add .
$ git commit -m "Procfile for Heroku"

Laravelプロジェクトの場合は、最小限の構成としてwebプロセス タイプを1つ、publicディレクトリをルートディレクトリとして起動します。

参考: Define a Procfile | Getting Started on Heroku with PHP | Heroku Dev Center

ちなみにProcfileがないと403 Forbiddenエラーになるので、忘れずに設定しましょう。

Heroku アプリケーションの作成

heroku createコマンドでアプリケーションを作成します。

$ heroku create <アプリケーション名>

アプリケーション名は省略すると任意の名前を割り振られます。
アプリケーション名はHeroku内でユニークである必要があるので衝突するとエラーになります。

実行例

$ heroku create laracal
Creating ⬢ laracal... done
https://laracal.herokuapp.com/ | https://git.heroku.com/laracal.git
$ heroku create laravel-calendar
Creating ⬢ laravel-calendar... !
 ▸    Name laravel-calendar is already taken

APP_KEYを生成し環境変数に登録

Herokuアプリ用のAPP_KEYを生成して、heroku config:setコマンドで環境変数に登録します。

$ php artisan key:generate --show
base64:9rd0cQwQmWAfFtf4/nu9VmGmftT9+q67AET5ehKohv0=
$ heroku config:set APP_KEY=base64:9rd0cQwQmWAfFtf4/nu9VmGmftT9+q67AET5ehKohv0=
Setting APP_KEY and restarting ⬢ sandbox-voice... done, v80
APP_KEY: base64: Vmbw5aw42nL5o81SygrnJ7WXRafYmKEKwqG7Yw7SOtw

1行で実行する場合

$ heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show)
Setting APP_KEY and restarting ⬢ laracal... done, v3
APP_KEY: base64:Vmbw5aw42nL5o81SygrnJ7WXRafYmKEKwqG7Yw7SOtw=

Herokuにpush

$ git push heroku master
...
remote: -----> Preparing runtime environment...
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 19.4M
remote: -----> Launching...
remote:        Released v6
remote:        https://laracal.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/laracal.git
   2e10d73..50cb859  datetime-with-timezone -> master

データベースにPostgreSQLを使用する

Heroku公式用意しているデータベース アドインはMySQLではなくPostgreSQLなので、Heroku Postgresを追加して設定していきます。

アドオンの追加

Heroku Postgresのアドオンの追加、デフォルトのプランはHobbyDev

$ heroku addons:create heroku-postgresql 
Creating heroku-postgresql on ⬢ laracal... free
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-aerodynamic-99493 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation

環境変数、DATABASE_URLにPostgresqlデータベースの認証情報がセットされたことを確認できます。

$ heroku config:get DATABASE_URL
postgres://chneewbwonqpop:15fab00731193f2347d9162586bc246c7b0b52948d6582e10cfa71433bc949dd@ec2-34-193-117-204.compute-1.amazonaws.com:5432/d2utb0ennie4t

Laravelのconfig/database.phpを確認すると、デフォルトでurlは環境変数DATABASE_URLから読み込むように定義されています。

// config/database.php
        'pgsql' => [
            'driver' => 'pgsql',
            'url' => env('DATABASE_URL'),
            ...
        ],

urlによる接続設定は、hostportdatabaseusernamepasswordによる設定よりも優先されるため、プロジェクト側での変更は特に必要がありません。

注意: Heroku Postgres接続情報はDATABASE_URLを必ず使用するようにします。Heroku Postgresはメンテナンス後にインスタンスが変わる場合がありますが、Herokuはメンテナンス時にDATABASE_URLも自動で変更してくれるためメンテナンス時に特に対応が不要になります。

接続をpgsqlに変更

このままではデフォルトの「mysql」の接続設定が使われてしまうため、環境変数DB_CONNECTIONに「pgsql」を登録します。

$ heroku config:set DB_CONNECTION=pgsql
Setting DB_CONNECTION and restarting ⬢ laracal... done, v9
DB_CONNECTION: pgsql

Heroku Postgreに対してマイグレーションを実行

heroku runコマンドを使います。
プロダクションだけどマイグレーション実行しますか?と聞かれるので「yes」を入力します。

$ heroku run "php artisan migrate"
Running php artisan migrate on ⬢ laracal... up, run.1070 (Free)
**************************************
*     Application In Production!     *
**************************************

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

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.03 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.02 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Migrating: 2019_12_06_073040_create_events_table
Migrated:  2019_12_06_073040_create_events_table (0.02 seconds)
Migrating: 2020_06_07_141049_create_settings_table
Migrated:  2020_06_07_141049_create_settings_table (0.02 seconds)

ログ出力

最後にheroku logsコマンドでログを参照できるように、チャンネルを「errorlog」に変更しておきます。

$ heroku config:set LOG_CHANNEL=errorlog
Setting LOG_CHANNEL and restarting ⬢ laracal... done, v10
LOG_CHANNEL: errorlog

Herokuでのログ出力については、以前の記事「HerokuでLaravel 6のログをPapertrailに出力する」も参照ください。

, ,