アイレット株式会社 DX開発事業部 IoT×クラウドセクション コアエンジニアリンググループの井上です!

前々回の記事:Laravel on Cloud Run:gcloud run jobs executeで複数引数を扱う方法では、
Cloud Run Jobs における複数引数の渡し方について解説しました。
また、前回の記事:Laravel on Cloud Run:DBをプライベート化した本番環境で、安全にマイグレーションを実行する方法では、
DBをプライベート化した環境でのマイグレーション実行についても触れました。

課題:直接インスタンス化すると実行できない?

Laravelのマイグレーションファイル内でマスターデータなどを投入したい際、以下のようにSeederクラスを直接呼び出すコードも一般的かと思います。

// web/app/database/migrations/0001_01_01_000000_create_xxxxx_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Database\Seeders\XxxxxSeeder;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // Schema::create();の記述

        // // Seeder実行
        (new XxxxxSeeder())->run();
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('xxxxx');
    }
};

ローカル環境や通常のサーバー環境ではこれでも動作しますが、
Cloud Run Jobs(コンテナ環境)で実行した際、クラスのオートロードの関係や実行コンテキストの違いにより、うまく動作しないケースがありました。

解決策:Artisan::call を経由させる

この問題を解決するために、直接クラスを呼び出すのではなく、Artisan::call を経由して Seeder を実行する形に変更しました。

// web/app/database/migrations/0001_01_01_000000_create_xxxxx_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Artisan;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // Schema::create();の記述

        // Seeder実行(Artisan経由)
        Artisan::call('db:seed', [
            '--class' => 'Database\\Seeders\\XxxxxSeeder'
        ]);
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('xxxxx');
    }
};

なぜこの変更が必要だったのか

  • 依存関係の解決: Artisan::call を使うことで、Laravelフレームワークが持つサービスコンテナやオートローダーの仕組みを正しく通して実行されるため、コンテナ環境特有のパスの問題を回避できます。
  • 実行の堅牢性: 直接 run() メソッドを叩くよりも、コマンドライン経由と同じ挙動になるため、ログの出力やエラーハンドリングがLaravelの標準仕様に則って行われ、デバッグが容易になります。

終わりに

Cloud Run Jobs のようなサーバーレスコンテナ環境では、「できるだけフレームワークの標準機能(Artisan)に乗っかる」ことが、予期せぬエラーを防ぐ近道です。

もしマイグレーションの中でデータ投入がうまくいかず悩んでいる方がいれば、ぜひこの方法を試してみてください!