$ composer create-project –prefer-dist laravel/laravel stancl
$ cd stancl
$ composer require laravel/jetstream
$ php artisan jetstream:install livewire
$ composer require stancl/tenancy
$ php artisan tenancy:install
$ php artisan migrate
mysql> show tables;
+————————+
| Tables_in_stancl |
+————————+
| domains |
| failed_jobs |
| migrations |
| password_resets |
| personal_access_tokens |
| sessions |
| tenants |
| users |
+————————+
8 rows in set (0.01 sec)
config/app.php
App\Providers\TenancyServiceProvider::class,
app/Models/Tenant.php
use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
use Stancl\Tenancy\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\Concerns\HasDatabase;
use Stancl\Tenancy\Database\Concerns\HasDomains;
class Tenant extends BaseTenant implements TenantWithDatabase {
use HasDatabase, HasDomains;
}
config/tenancy.php
'tenant_model' => \App\Models\Tenant::class,
### Central routes
app/Providers/RouteServiceProvider.php
protected function mapWebRoutes(){
foreach($this->centralDomains() as $domain){
Route::middleware('web')
->domain($domain)
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
}
protected function mapApiRoutes(){
foreach($this->centralDomains() as $domain){
Route::prefix('api')
->domain($domain)
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
protected function centralDomains(): array {
return config('tenancy.central_domains');
}
public function boot()
{
$this->configureRateLimiting();
// $this->routes(function () {
// Route::prefix('api')
// ->middleware('api')
// ->namespace($this->namespace)
// ->group(base_path('routes/api.php'));
// Route::middleware('web')
// ->namespace($this->namespace)
// ->group(base_path('routes/web.php'));
// });
$this->mapWebRoutes();
$this->mapApiRoutes();
}
config/tenancy.php
'central_domains' => [
// '127.0.0.1',
'192.168.33.10',
// 'localhost',
],
routes/tenant.php
Route::get('/', function () {
dd(\App\Models\User::all());
return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id');
});
move the users table migration (the file database/migrations/2014_10_12_000000_create_users_table.php or similar) to database/migrations/tenant.
php artisan tinker
>>> $tenant1->domains()->create([‘domain’ => ‘hoge.192.168.33.10’]);
=> Stancl\Tenancy\Database\Models\Domain {#4734
domain: “hoge.192.168.33.10”,
tenant_id: “hoge”,
updated_at: “2021-08-08 11:59:44”,
created_at: “2021-08-08 11:59:44”,
id: 1,
tenant: App\Models\Tenant {#4792
id: “hoge”,
created_at: “2021-08-08 11:59:35”,
updated_at: “2021-08-08 11:59:35”,
data: null,
tenancy_db_name: “tenanthoge”,
},
}
>>> $tenant2 = App\Models\Tenant::create([‘id’ => ‘bar’]);
=> App\Models\Tenant {#4794
id: “bar”,
data: null,
updated_at: “2021-08-08 11:59:50”,
tenancy_db_name: “tenantbar”,
}
>>> $tenant2->domains()->create([‘domain’ => ‘bar.192.168.33.10’]);
=> Stancl\Tenancy\Database\Models\Domain {#4786
domain: “bar.192.168.33.10”,
tenant_id: “bar”,
updated_at: “2021-08-08 11:59:55”,
created_at: “2021-08-08 11:59:55”,
id: 2,
tenant: App\Models\Tenant {#3788
id: “bar”,
created_at: “2021-08-08 11:59:50”,
updated_at: “2021-08-08 11:59:50”,
data: null,
tenancy_db_name: “tenantbar”,
},
}
$ php artisan make:seeder TenantTableSeeder
public function run()
{
App\Tenant::all()->runForEach(function () {
factory(App\User::class)->create();
});
}
mysql> select * from tenants;
+——+———————+———————+———————————–+
| id | created_at | updated_at | data |
+——+———————+———————+———————————–+
| bar | 2021-08-08 11:59:50 | 2021-08-08 11:59:50 | {“tenancy_db_name”: “tenantbar”} |
| foo | 2021-08-08 11:53:06 | 2021-08-08 11:53:06 | {“tenancy_db_name”: “tenantfoo”} |
| hoge | 2021-08-08 11:59:35 | 2021-08-08 11:59:35 | {“tenancy_db_name”: “tenanthoge”} |
+——+———————+———————+———————————–+
流れはわかったが、名前解決が出来ないな。。。
これも、ドメインでやるのかな。
1. お名前.comでドメインを取得してVPSにデプロイします。
2. お名前.com側ではDNS側でAレコードをワイルドカードで設定、VPS側ではCNAMEを設定して再度試します。
できたーーーーーーーーーーーーーーーーーーああああああああああああ
ウヒョーーーーーーーーー
database/tenant/* の中に、テナント用のmigration fileを作るわけね。
マルチテナントの開発の場合は、localhostや192.168.33.10などは名前解決できないので、ドメインを取得してテストする必要がある。
うむ、なかなか大変だわこれ。