Complete Guide to Integrating Tenancy for Laravel v3
Multi-tenancy is a crucial requirement for many modern SaaS applications. The Tenancy for Laravel package (formerly known as hyn/multi-tenant) provides an elegant solution for implementing multi-tenancy in Laravel applications. This guide will walk you through the complete integration process for version 3 of the package.
Prerequisites
- Laravel 8.x or higher
- PHP 8.0 or higher
- Composer installed
- Database server (MySQL, PostgreSQL, SQLite, or SQL Server)
Step 1: Installation
First, install the package via Composer:
composer require stancl/tenancy
Then, publish the configuration file:
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=config
Step 2: Database Configuration
Tenancy v3 uses a central database for tenant metadata and separate databases for each tenant. Configure your central database connection in .env
:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=central_database
DB_USERNAME=root
DB_PASSWORD=
Configure the tenancy settings in config/tenancy.php
:
'database' => [
'based_on' => 'mysql', // The connection to use as a base for tenant databases
'prefix' => 'tenant_',
'suffix' => '',
],
Step 3: Setting Up Tenants
Run the migrations to create the tenants table:
php artisan tenancy:install
Then migrate:
php artisan migrate
Create a Tenant model and migration:
php artisan make:model Tenant -m
Update the migration:
Schema::create('tenants', function (Blueprint $table) {
$table->string('id')->primary();
// Your custom columns
$table->string('name');
$table->string('domain')->unique();
$table->json('data')->nullable();
$table->timestamps();
});
Step 4: Configuring Routes
Update your routes/web.php
to handle tenant routes:
Route::middleware([
'web',
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class,
])->group(function () {
// Your tenant routes here
Route::get('/', function () {
return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id');
});
});
// Central domain routes
Route::get('/', function () {
return 'This is the central domain.';
});
Step 5: Tenant Identification
Configure how tenants are identified in config/tenancy.php
:
'tenant_model' => \App\Models\Tenant::class,
'identification_middleware' => [
InitializeTenancyByDomain::class,
// Or InitializeTenancyBySubdomain::class,
// Or InitializeTenancyByPath::class,
],
Step 6: Creating Tenants
Create a tenant programmatically:
$tenant = Tenant::create([
'id' => 'acme',
'name' => 'ACME Corp',
'domain' => 'acme.yourdomain.com',
]);
$tenant->domains()->create([
'domain' => 'acme.yourdomain.com',
]);
Step 7: Running Tenant-Specific Commands
You can run artisan commands for specific tenants:
php artisan tenancy:run migrate --tenant=acme
Or for all tenants:
php artisan tenancy:run migrate --all
Step 8: Storage Configuration
Configure tenant-specific storage in config/filesystems.php
:
'tenant' => [
'driver' => 'local',
'root' => storage_path('app/tenant/' . tenant('id')),
],
Step 9: Cache Configuration
Configure tenant-specific cache in config/cache.php
:
'tenant' => [
'driver' => 'database',
'table' => 'tenant_cache',
'connection' => 'tenant',
],
Step 10: Queue Configuration
For tenant-aware queues, update your queue configuration:
'connections' => [
'tenant' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
'after_commit' => false,
],
],
Advanced Features
Tenant Assets
Serve tenant-specific assets:
Route::get('/assets/{path}', function ($path) {
return response()->file(storage_path("app/tenant/" . tenant('id') . "/assets/$path"));
})->where('path', '.*');
Custom Tenant Database Creation
Override the default database creation logic:
Event::listen(TenantCreated::class, function (TenantCreated $event) {
$event->tenant->run(function () {
// Custom database setup
Artisan::call('migrate', [
'--path' => 'database/migrations/tenant',
'--force' => true,
]);
// Seed data
Artisan::call('db:seed', [
'--class' => 'TenantDatabaseSeeder',
]);
});
});
Central Domain Access to Tenant Data
Access tenant data from the central domain:
tenancy()->initialize('tenant-id');
// Now you can access tenant data
tenancy()->end();
Troubleshooting
- Make sure your tenant domains are properly configured in your hosts file or DNS
- Check that your database user has permissions to create databases
- Verify that your cache and session drivers are tenant-aware
- Ensure all necessary middleware is applied to your routes
Conclusion
Tenancy for Laravel v3 provides a powerful and flexible solution for implementing multi-tenancy in your Laravel applications. By following this guide, you've set up a robust multi-tenant architecture that can scale with your application's needs.
For more advanced features and customization options, refer to the official documentation.
No comments:
Post a Comment