SailのDockerコンテナにデーベースを2つ作る
まず、.envにADMIN用の接続設定がある前提で、2つめのデータベースを作成するスクリプトを作成する。
# 管理者テーブルの参照先
ADMIN_HOST=mysql
ADMIN_PORT=3306
ADMIN_DATABASE=my_admin
ADMIN_USERNAME=my_user
ADMIN_PASSWORD=my_password
docker/mysql/create-second-database.sh
#!/bin/bash
# コンテナ初期化時に実行されるスクリプト
# 環境変数を使用してデータベースとユーザーを作成
mysql -u root -p"${MYSQL_ROOT_PASSWORD}" <<-EOSQL
CREATE DATABASE IF NOT EXISTS \`${ADMIN_DATABASE}\`;
CREATE USER IF NOT EXISTS '${ADMIN_USERNAME}'@'%' IDENTIFIED BY '${ADMIN_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${ADMIN_DATABASE}\`.* TO '${ADMIN_USERNAME}'@'%';
FLUSH PRIVILEGES;
EOSQL
docker-compose.yml にデータベース作成スクリプトの実行を追加。
services:
mysql:
volumes:
- 'sail-mysql:/var/lib/mysql'
- './docker/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
# 以下を追加
- './docker/mysql/create-second-database.sh:/docker-entrypoint-initdb.d/create-second-database.sh'
マイグレーションに新しい接続先を定義
config/database.php に管理者用の接続先を定義して、マイグレーション単位で connection を指定できる。
'connections' => [
'admin' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('ADMIN_HOST', '127.0.0.1'),
'port' => env('ADMIN_PORT', '3306'),
'database' => env('ADMIN_DATABASE', 'forge'),
'username' => env('ADMIN_USERNAME', 'forge'),
'password' => env('ADMIN_PASSWORD', ''),
'unix_socket' => env('ADMIN_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
ただし、sail artisan migrate:fresh --seed
でデータベースを作成し直したときにロールバックは主データベースのテーブルにしか働かなかったので、個別に dropIfExists する。
return new class extends Migration
{
protected $connection = 'admin';
/**
* Run the migrations.
*/
public function up(): void
{
Schema::dropIfExists('destinations');
Schema::create('admins', function (Blueprint $table) {
2つめの接続設定
config/auth.php で管理者用のプロバイダを定義するが、これだけだとセカンドデータベースに接続しにいかなかった。
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\Users::class,
],
'admins' => [
'driver' => 'admin',
'model' => App\Models\Admin::class,
'connection' => 'admin',
],
モデルにも connection を指定することで解決した。
class Admin extends Authenticatable
{
protected $connection = 'admin';