PHPackages                             doctrine-tenancy/laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. doctrine-tenancy/laravel

ActiveLibrary[Database &amp; ORM](/categories/database)

doctrine-tenancy/laravel
========================

A comprehensive multi-tenancy package for Laravel applications using Doctrine ORM

1.0.0(8mo ago)07MITPHPPHP ^8.2CI passing

Since Sep 15Pushed 8mo agoCompare

[ Source](https://github.com/stakio/laravel-doctrine-tenancy)[ Packagist](https://packagist.org/packages/doctrine-tenancy/laravel)[ Docs](https://github.com/stakio/laravel-doctrine-tenancy)[ RSS](/packages/doctrine-tenancy-laravel/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (8)Versions (2)Used By (0)

Laravel Doctrine Tenancy
========================

[](#laravel-doctrine-tenancy)

Professional multi-tenancy for Laravel using Doctrine ORM. Clean APIs, job-based database operations, and first-class portability.

Highlights
----------

[](#highlights)

- **Database-per-tenant** architecture
- **Automatic routing** via a Smart Entity Manager
- **Domain/Header** based tenant resolution
- **Job-based ops** (migrate/delete) with retries and optional sync
- **Rollback-aware migrations** and structured logging
- **Laravel 11/12** and **Doctrine ORM 3**

Installation
------------

[](#installation)

```
composer require doctrine-tenancy/laravel
```

Then run the installer:

```
# Publish config only (recommended)
php artisan tenancy:install

# Publish config + core migration stubs (optional)
php artisan tenancy:install --migrations

# You can always publish stubs later
php artisan vendor:publish --tag=tenancy-migrations-stub
```

Run your application migrations (includes the published `tenants` and `tenant_domains` if you chose to publish stubs):

```
php artisan migrate
```

Usage
-----

[](#usage)

### 1) Configure Entity Routing

[](#1-configure-entity-routing)

```
// config/tenancy.php
'entity_routing' => [
    'central' => [
        'App\Entities\Clinic',        // Shared across all tenants
    ],
    'tenant' => [
        'App\Entities\Patient',       // Tenant-specific data
    ],
],
```

### 2) Add Middleware

[](#2-add-middleware)

```
Route::middleware(['resolve.tenant'])->group(function () {
    // Your tenant-aware routes
    Route::get('/patients', [PatientController::class, 'index']);
});
```

### 3) Use in Controllers

[](#3-use-in-controllers)

```
use Doctrine\ORM\EntityManagerInterface;

class PatientController
{
    public function __construct(
        private EntityManagerInterface $entityManager
    ) {}

    public function index()
    {
        // Automatically routes to tenant database
        $patients = $this->entityManager->getRepository(Patient::class)->findAll();
        return response()->json($patients);
    }
}
```

Tenant Resolution
-----------------

[](#tenant-resolution)

- **Domain-based**: `tenant1.example.com` → `tenant1`
- **Header-based**: set `X-Tenant-ID: `

Database Management (Jobs)
--------------------------

[](#database-management-jobs)

All tenant DB operations run as jobs. Use `--sync` for blocking execution.

### Migrate

[](#migrate)

```
# Asynchronous (recommended)
php artisan tenant:database migrate {tenant-id}

# Synchronous (blocks until done)
php artisan tenant:database migrate {tenant-id} --sync

# Optional email notification on completion/failure
php artisan tenant:database migrate {tenant-id} --notify=admin@example.com
```

### Delete

[](#delete)

```
# Asynchronous
php artisan tenant:database delete {tenant-id}

# Synchronous
php artisan tenant:database delete {tenant-id} --sync
```

### Queue Management

[](#queue-management)

```
# Run workers for tenant queues
php artisan queue:work --queue=tenant-migrations,tenant-deletions

# Check failed jobs
php artisan queue:failed
```

Custom Entities
---------------

[](#custom-entities)

Create your own tenant and domain entities by implementing the required interfaces:

```
use LaravelDoctrine\Tenancy\Contracts\TenantEntityInterface;
use LaravelDoctrine\Tenancy\Contracts\TenantIdentifier;

class Clinic implements TenantEntityInterface
{
    public function getId(): UuidInterface
    {
        return $this->id;
    }

    public function name(): TenantName
    {
        return new TenantName($this->name);
    }

    public function isActive(): bool
    {
        return $this->isActive;
    }

    public function toIdentifier(): TenantIdentifier
    {
        return new TenantId($this->id);
    }
}
```

Then configure in `config/tenancy.php`:

```
'tenant_entity' => App\Entities\Clinic::class,
'domain_entity' => App\Entities\ClinicDomain::class,
```

Configuration
-------------

[](#configuration)

```
// config/tenancy.php
return [
    'enabled' => true,

    'tenant_entity' => \LaravelDoctrine\Tenancy\Domain\Tenant::class,
    'domain_entity' => \LaravelDoctrine\Tenancy\Domain\DomainEntity::class,

    'entity_routing' => [
        'central' => ['App\Entities\Clinic'],
        'tenant' => ['App\Entities\Patient'],
    ],

    'database' => [
        'central_connection' => env('TENANCY_CENTRAL_CONNECTION', 'default'),
        'prefix' => env('TENANCY_DATABASE_PREFIX', 'tenant_'),
    ],

    'migrations' => [
        'tenant_path' => 'database/migrations/tenant',
    ],

    'logging' => [
        'channel' => env('TENANCY_LOG_CHANNEL', null), // Optional dedicated channel
    ],

    'identification' => [
        'header_name' => env('TENANCY_HEADER_NAME', 'X-Tenant-ID'),
        'excluded_subdomains' => ['www', 'api', 'admin'],
    ],
];
```

### Publishing

[](#publishing)

```
# Config
php artisan vendor:publish --tag=tenancy-config

# Migration stubs (optional)
php artisan vendor:publish --tag=tenancy-migrations-stub
```

Publishing stubs copies `tenants` and `tenant_domains` migrations into `database/migrations/`. Use them as-is or adapt for custom entities.

Supported Database Drivers
--------------------------

[](#supported-database-drivers)

This package supports the following database drivers:

- **MySQL** 5.7+ / **MariaDB** 10.3+
- **PostgreSQL** 10+
- **SQLite** 3.8+

### Database-Specific Features

[](#database-specific-features)

- **MySQL/MariaDB**: Full support with `INFORMATION_SCHEMA` queries for database existence checks
- **PostgreSQL**: Full support with `pg_database` queries and connection termination for safe drops
- **SQLite**: Basic support (databases are files, created on first connection)

Versioning Strategy
-------------------

[](#versioning-strategy)

This package follows [Semantic Versioning](https://semver.org/):

- **Major versions** (1.0, 2.0): Breaking changes that require code modifications
- **Minor versions** (1.1, 1.2): New features, backward compatible
- **Patch versions** (1.1.1, 1.1.2): Bug fixes, backward compatible

### Breaking Changes Policy

[](#breaking-changes-policy)

- Breaking changes are only introduced in major versions
- Deprecations are announced at least one minor version before removal
- Migration guides are provided for major version upgrades

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11.0+ or 12.0+
- Doctrine ORM 3.0+

License
-------

[](#license)

MIT

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance61

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

243d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/840819b79e7a21908e3bef609a4f02fcbe0b485b10852e2cb695ab4c0d3a72c6?d=identicon)[faisalabuzaid](/maintainers/faisalabuzaid)

---

Top Contributors

[![faisalabuzaid](https://avatars.githubusercontent.com/u/74982616?v=4)](https://github.com/faisalabuzaid "faisalabuzaid (14 commits)")

---

Tags

laraveldatabaseormdoctrinesaasmulti-tenancytenancy

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/doctrine-tenancy-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/doctrine-tenancy-laravel/health.svg)](https://phpackages.com/packages/doctrine-tenancy-laravel)
```

###  Alternatives

[scienta/doctrine-json-functions

A set of extensions to Doctrine that add support for json query functions.

58523.9M36](/packages/scienta-doctrine-json-functions)[laravel-doctrine/orm

An integration library for Laravel and Doctrine ORM

8425.3M87](/packages/laravel-doctrine-orm)[hyn/multi-tenant

Run multiple websites using the same laravel installation while keeping tenant specific data separated for fully independant multi-domain setups.

2.6k1.1M9](/packages/hyn-multi-tenant)[laravel-doctrine/migrations

Doctrine Migrations for Laravel

782.8M16](/packages/laravel-doctrine-migrations)[laravel-doctrine/fluent

A fluent PHP mapping driver for Doctrine2.

43430.3k13](/packages/laravel-doctrine-fluent)[laravel-doctrine/acl

ACL for Laravel and Doctrine

44445.3k7](/packages/laravel-doctrine-acl)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
