LaravelアプリのセッションをHeroku Redisに保存する設定する手順についてまとめてみます。
HerokuでRedisを利用する場合、現在(2019.11)は公式のHeroku Redisを利用できます。
公式ドキュメントはこちら: Heroku Redis | Heroku Dev Center
セッションをキャッシュに入れるのはなぜか?
ところで、改めてHerokuでセッションをRedisなどのストレージに保存する必要があるのか?ってことなんですが、試しにfree Dynoを使っていてすぐにDynoがsleepしてしまうような場合は、DynoのファイルシステムはEphemeral Disk(揮発性ディスク)なのでRedisなどに保存しておかないとsleepするたびにセッションが切れてしまいます。
また、Hobby以上のDynoの場合でも1日一回は再起動されるとのことなのでやはりキャッシュストレージに入れておいた方が良さそうです。
参照: Restarting | Dynos and the Dyno Manager
一方、1日1回くらいならまあいいかとしてDynoが複数の場合はでは必要なのか?って話ですが、セッション固定機能のSession Affinityを使えば問題ないかもしれません。
とはいえよくわからないタイミングでセッションが切れるのは嫌なので、やはりセオリー通りセッションはRedisなどのストレージに保存しておくのがBetterなのではと言ったところです。
いまいち歯切れがわすいですが。。
セッションストレージをHeroku Redisに設定する手順
まずは、Heroku Redisアドオンを追加
$ heroku addons:create heroku-redis
Creating heroku-redis on ⬢ xxxxxx-xxxxx... free
Your add-on should be available in a few minutes.
! WARNING: Data stored in hobby plans on Heroku Redis are not persisted.
redis-deep-37043 is being created in the background. The app will restart when complete...
Use heroku addons:info redis-deep-37043 to check creation progress
Use heroku addons:docs heroku-redis to view documentation
アドオンをインストールすると環境変数REDIS_URL
が追加されます。
$ heroku config | grep REDIS
REDIS_URL: redis://h:p26678e703cdfcb924c874797e6bfa151da85bfe0a2e24d410ff29f911b6d96d7@ec2-3-234-12-25.compute-1.amazonaws.com:25129
続いて、Laravel側の設定をしていきます。
Redisのドライバーを追加します。
$ composer require predis/predis
Herokuの環境変数で、セッションドライバーをredis
にセットします。
$ heroku config:set SESSION_DRIVER=redis
次にRedisの接続情報を設定します。
Redisの接続情報は、config/database.php
のredis
の箇所で環境変数 REDIS_HOST
、REDIS_PASSWORD
、REDIS_PORT
から値を取得しています。
// config/database.php
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_',
],
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
ところで、Heroku Redisはメンテナンスでインスタンスが切り替わることがあり、切り替わった場合は自動でREDIS_URLの値も更新されます。つまりHeroku Redisアドオンを追加時にセットされたREDIS_URLを分解して値を直接上記の環境変数にセットするのはNGで、config/database.php
ファイルの先頭でREDIS_URLを分解して各環境変数にセットするロジックを入れておくのが良いようです。
(この情報についてはHerokuのドキュメントなど一次ソースを探しましたが見つかりませんでした、経験則による情報なります。)
// config/database.php
<?php
use Illuminate\Support\Str;
if (getenv('REDIS_URL')) {
$url = parse_url(getenv('REDIS_URL'));
putenv('REDIS_HOST='.$url['host']);
putenv('REDIS_PORT='.$url['port']);
putenv('REDIS_PASSWORD='.$url['pass']);
}
return [
...
];
以上で設定完了です。