はじめに
Laravelで本番環境だけmigrateが反映されていませんでした。
結論、以下のメッセージが表示されて、マイグレーションが実行されていなかったことが原因でした。
**************************************
* Application In Production! *
**************************************
背景
Laravel初心者です。
EC2-RDS環境へCodeDeployを使用してLaravelのアプリケーションをデプロイしているのですが、
dev,stgへのDB migrationはうまくいくのに、prodのみ実行されていませんでした。
CodeDeployより実行されるシェルの中にphp artisan migrate
を記載していたのですが、
デプロイ時にはエラーにはなっておらずアプリケーションの反映もできているが、DBのみ変更が反映されていない状態となっていました。
EC2よりmigrateのステータスを確認すると以下のような感じでした。
(テーブル名は隠しています)
$ php artisan migrate:status
+------+----------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+----------------------------------------------------+-------+
| Yes | 2021_06_11_114558_・・・ | 1 |
| Yes | 2021_06_14_080808_・・・ | 1 |
| Yes | 2021_07_28_120012_・・・ | 1 |
| Yes | 2021_07_28_132034_・・・ | 1 |
| Yes | 2021_07_29_035254_・・・ | 1 |
| No | 2021_09_24_150711_・・・ | |
| No | 2021_10_11_153540_・・・ | |
| No | 2021_10_22_140438_・・・ | |
| No | 2021_10_27_092010_・・・ | |
| No | 2021_10_28_143847_・・・ | |
+------+----------------------------------------------------+-------+
本格的に解決に乗り出していなかったこともありますが、
原因がわからず解決するまでの間は、本番環境のみ直接DBへSQLを実行してDBの変更を反映していました。
原因
EC2へログインしCodeDeployのログを見てみると、本番環境だけど本当に実行していいの?
という確認メッセージが出ているようでした。
cat /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log
〜省略〜
**************************************
* Application In Production! *
**************************************
Do you really wish to run this command? (yes/no) [no]:
> Command Canceled!
その確認に回答していないため、コマンドがキャンセルされてしまっていましたようです。
envがproductionの場合のみ確認メッセージが出るようで、devやstg環境では発生していなかったのもそのためです。
※先に記載したmigrate:status
で7月まではうまくいっていた原因は、その期間はprodで実行していなかったためのようです。
解決策
CodeDeployから実行されるシェル内のmigrateコマンドにforceオプションを付けることで、
productionでも確認メッセージなしで実行することができました。
php artisan migrate --force
その他対応
上記の通り本番環境のみ直接DBへSQLを実行していたため、そのままmigrateコマンドを実行することはできませんでした。
今までのmigration文のDB変更は済んでいるため、migrateを実行したことにする必要がありました。
migrateを実行したことにするためにはDBに作成されているmigrations
テーブルを変更することでできるようです。
(migrateの履歴を管理しているテーブル)
stg環境のmigrations
テーブルと比較しながら以下のようなインサート文を実行しました。
idはオートインクリメント、batchは現在のbatch番号+1しています。(ロールバックに関わる?)
insert into migrations (migration,batch) values('2021_09_24_150711_・・・','2');
insert into migrations (migration,batch) values('2021_10_11_153540_・・・','2');
insert into migrations (migration,batch) values('2021_10_22_140438_・・・','2');
insert into migrations (migration,batch) values('2021_10_27_092010_・・・','2');
insert into migrations (migration,batch) values('2021_10_28_143847_・・・','2');
実行後EC2よりmigrateのステータスを確認すると、反映済みとなっているようでした。
$ php artisan migrate:status
+------+----------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+----------------------------------------------------+-------+
| Yes | 2021_06_14_080808_・・・ | 1 |
| Yes | 2021_07_28_120012_・・・ | 1 |
| Yes | 2021_07_28_132034_・・・ | 1 |
| Yes | 2021_07_29_035254_・・・ | 1 |
| Yes | 2021_09_24_150711_・・・ | 2 |
| Yes | 2021_10_11_153540_・・・ | 2 |
| Yes | 2021_10_22_140438_・・・ | 2 |
| Yes | 2021_10_27_092010_・・・ | 2 |
| Yes | 2021_10_28_143847_・・・ | 2 |
+------+----------------------------------------------------+-------+
その後、CodeDeployを通した新しいmigrationの取り込みもうまくいきました。
$ php artisan migrate:status
+------+----------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+----------------------------------------------------+-------+
| Yes | 2021_06_14_080808_・・・ | 1 |
| Yes | 2021_07_28_120012_・・・ | 1 |
| Yes | 2021_07_28_132034_・・・ | 1 |
| Yes | 2021_07_29_035254_・・・ | 1 |
| Yes | 2021_09_24_150711_・・・ | 2 |
| Yes | 2021_10_11_153540_・・・ | 2 |
| Yes | 2021_10_22_140438_・・・ | 2 |
| Yes | 2021_10_27_092010_・・・ | 2 |
| Yes | 2021_10_28_143847_・・・ | 2 |
| Yes | 2021_11_15_072434_・・・ | 3 |
+------+----------------------------------------------------+-------+
おわりに
productionの場合に挙動が変わる?コマンドって親切とは思いますが、こういったことが起こるんですね。
CodeDeployのログを確認する際にEC2に潜らなくては確認できないのは不便なので、CloudWatchに連携したいと思います。