CÓMO CONSTRUIR APLICACIONES MULTI-TENANT CON LARAVEL
Multi-tenant en Laravel es un patrón de arquitectura que permite que una sola aplicación Laravel, una sola instalación, sirva de forma simultánea a múltiples clientes, empresas u organizaciones, llamados tenants o inquilinos, pero manteniendo los datos, usuarios, configuraciones y lógica de cada uno completamente aislados y separados entre sí.- Decidir la estrategia de aislamiento de datos
Estrategia Aislamiento Complejidad Costo DB Recomendado para (2026) Paquete más usado actualmente Single Database Lógico (tenant_id) ★☆☆ Muy bajo Proyectos pequeños/medianos, rápido prototipo spatie/laravel-multitenancy o tenancyforlaravel (modo single) Database per Tenant Físico (BD separada) ★★★ Alto SaaS serios, GDPR/HIPAA, alta seguridad stancl/tenancy (archtechx/tenancy) Schema per Tenant Físico (esquema) ★★☆ Medio Buen balance (PostgreSQL recomendado) — - Si se busca rapidez y simplicidad → empezar con single database + spatie/laravel-multitenancy
- Si se planea un SaaS real con crecimiento → es mejor stancl/tenancy (Database per Tenant o Schema). Es el paquete más maduro, mantenido y con más features out-of-the-box.
- Paquetes recomendados
Paquete Autor Tipo más fuerte Estrellas GitHub (aprox) Comunidad activa Recomendado si... stancl/tenancy Samuel Štancl Database / Schema ~3.5k+ Muy alta Quieres el paquete más completo y automático spatie/laravel-multitenancy Spatie Single DB (muy flexible) ~2.8k+ Muy alta Proyecto simple o ya tienes single DB tenancy/tenancy (viejo) — — — Baja - Implementación recomendada con stancl/tenancy (Database per Tenant)
- Paso 1: Instalación
composer create-project laravel/laravel saas-app cd saas-app composer require stancl/tenancy - Paso 2: Publicar e instalar
Esto crea:Modelo Tenant por defecto, migraciones central y tenant y un fichero de configuración "config/tenancy.php".php artisan tenancy:install -
Paso 3: Configura identificación del tenant (lo más común es por subdominio)
// config/tenancy.php 'central_domains' => [ 'localhost', '127.0.0.1', 'saas-app.test', ], 'identification' => [ 'by' => 'subdomain', // o 'domain', 'path', 'header', etc. ], -
Paso 4: Personaliza el modelo Tenant (muy recomendado)
// app/Models/Tenant.php namespace App\Models; 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; protected $fillable = ['id', 'name', 'plan', 'data']; // agrega lo que necesites } -
Paso 5: Migra bases de datos
# Migraciones centrales (users globales, tenants, etc.) php artisan migrate # Crea una base de datos de prueba para un tenant php artisan tenants:seed --class=DatabaseSeeder -
Paso 6: Rutas multi-tenantphp
// routes/tenant.php (creado automáticamente) Route::middleware(['web', 'tenancy'])->group(function () { Route::get('/', function () { return 'Bienvenido al dashboard de ' . tenant('name'); }); }); -
Paso 7: Crear un tenant (ejemplo en un controlador o seeder)
Ahora accede a http://acme.localhost:8000 → verás solo los datos de ese tenant.use App\Models\Tenant; use Stancl\Tenancy\Database\Models\Domain; $tenant = Tenant::create([ 'id' => 'acme', 'name' => 'Acme Corp', ]); $tenant->domains()->create(['domain' => 'acme.localhost']);
- Paso 1: Instalación
- Features útiles que casi todos usanFiltrado automático de datos (ya lo hace el paquete).
- Jobs y Queues tenant-aware → configurado por defecto.
- Storage tenant-specific → storage_path('app/public/' . tenant('id')).
- Migrations por tenant → php artisan tenants:migrate.
- Comandos masivos → php artisan tenants:seed, tenants:cache:clear, etc..
- Alternativa: Single Database con SpatieSi prefieres empezar simple:
Luego usar traits como HasTenant en tus modelos y scopes globales.composer require spatie/laravel-multitenancy php artisan vendor:publish --provider="Spatie\Multitenancy\MultitenancyServiceProvider" --tag="migrations" php artisan migrate