withMySQLDatabase('testing') ->withMySQLUser('testing', 'testing') ->start(); // Stop and remove the container when the PHP process exits, even on // crashes or SIGINT. testcontainers-php has no built-in cleanup. register_shutdown_function(function () use ($container): void { $container->stop(); }); $host = $container->getHost(); $port = (string) $container->getFirstMappedPort(); // Set environment variables before Laravel boots so config/database.php // reads the dynamic host and port via env(). Both putenv() and $_ENV/$_SERVER // are needed because Laravel's env() helper checks multiple sources. $env = [ 'DB_CONNECTION' => 'mysql', 'DB_HOST' => $host, 'DB_PORT' => $port, 'DB_DATABASE' => 'testing', 'DB_USERNAME' => 'testing', 'DB_PASSWORD' => 'testing', ]; // Generate an APP_KEY if one is not already set, so tests can run // without a .env file (e.g. fresh worktrees, CI environments). if (empty($_SERVER['APP_KEY'] ?? $_ENV['APP_KEY'] ?? getenv('APP_KEY'))) { $env['APP_KEY'] = 'base64:'.base64_encode(random_bytes(32)); } foreach ($env as $key => $value) { putenv("{$key}={$value}"); $_ENV[$key] = $value; $_SERVER[$key] = $value; } }