hakam / multi-tenancy-bundle
Flexible and production-ready multi-tenancy bundle for Symfony.
Installs: 37 209
Dependents: 0
Suggesters: 0
Security: 0
Stars: 117
Watchers: 7
Forks: 34
Open Issues: 2
Type:symfony-bundle
pkg:composer/hakam/multi-tenancy-bundle
Requires
- php: ^8.2
- doctrine/doctrine-bundle: ^2.7
- doctrine/doctrine-migrations-bundle: ^3.0
- doctrine/orm: ^2.15 || ^3.0
- psr/cache: ^3.0
- symfony/cache-contracts: ^3.0
- symfony/config: ^6.4|^7.0
- symfony/dependency-injection: ^6.4|^7.0
- symfony/filesystem: ^6.4|^7.0
- symfony/http-kernel: ^6.4|^7.0
- symfony/var-exporter: ^6.4|^7.0|^8.0
Requires (Dev)
- dg/bypass-finals: ^1.9
- doctrine/doctrine-fixtures-bundle: ^3.6
- phpunit/phpunit: ^10.0
- symfony/phpunit-bridge: ^6.4|^7.0
- dev-master / 3.0.x-dev
- v3.0.0
- 2.x-dev
- v2.9.4
- v2.9.3
- v2.9.2
- v2.9.1
- v2.9.0
- v2.8.3
- v2.8.2
- v2.8.1
- v2.8.0
- 2.7.1
- 2.7.0
- v2.6.0
- v2.5.4
- v2.5.3
- v2.5.2.x-dev
- v2.5.2
- v2.5.1.x-dev
- v2.5.1
- v2.5.0
- v2.0.1
- v2.0.0
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.2
- dev-feature/add-custom-sehcema-per-tenant
- dev-feature/add-functional-testing
- dev-feature/add-tests
- dev-feature/add-integration-test
- dev-feature/add-code-coverage
- dev-feature/add-cache-and-manager-override
- dev-feature/add-testing-trait
- dev-feature/enhance-event-listener
- dev-feature/add-tenant-db-lifecycle-events
- dev-fix/disable-switching-if-the-same-params-used
- dev-feature/Add-automatic-tenant-resolver
- dev-add-integration-tests-suite
- dev-fix/69-skip-redundant-tenant-switch
- dev-fix/73-avoid-env-leak-in-configuration
- dev-46-get-the-data-from-the-main-database-instead-of-tenant-database
- dev-66-help-with-the-error
- dev-Bugfix/Migration-command-forces-dbId-with-getId-instead-of-using-the-configured-identifier-
- dev-Add-UUID-as-tenant-db-id
- dev-Supprot-Pluggable-TenantDbConfigurationInterface
- dev-Install-only-dist
- dev-create-db-async
- dev-dev
- dev-add-symfony-flex-contrib-recipes
- dev-Add-Tenant-Fixture-commands
- dev-Implement-Bulk-create-and-migrate-commands
- dev-fix-wrong-dir-check
- dev-40-question-multi-tenancy-with-multi-database
- dev-35-doctrine-dbal-4-multiple-changes-and-deprecations
- dev-25-deprecated-the-url-connection-parameter-dbal-36
- dev-Remove-php-deprecated-versions-
- dev-28-unable-to-use-dql-string_functions
- dev-Create-database-from-command
- dev-create-db-command
- dev-Add-github-actions
- dev-issues/13-Diff-command-Check-the-Main-db-if-the-Tenant-DbId-is-NULL
- dev-Non-existent-service
This package is auto-updated.
Last update: 2026-02-23 10:52:06 UTC
README
📚 Full Documentation: Documentation
🧩 Overview
The Symfony Multi-Tenancy Bundle enables scalable, production-ready multi-tenancy for Symfony applications.
Ideal for SaaS platforms, region-based services, and multi-vendor e-commerce systems, this bundle is built around a database-per-tenant architecture, giving each tenant:
- A fully isolated database
- Independent schema and migrations
- Configurable connection parameters (host, driver, credentials)
It integrates seamlessly with Doctrine and Symfony's service container, offering:
- Automatic tenant database switching at runtime via
SwitchDbEvent - Automatic tenant resolution from HTTP requests (subdomain, path, header, or custom)
- Separate migration and fixture paths for main vs. tenant databases
- Dedicated
TenantEntityManagerservice for runtime isolation
For full usage examples and advanced configuration, see the documentation.
🔄 Automatic Tenant Resolution (v3.0.0+)
Automatically resolve the current tenant from incoming HTTP requests — no manual event dispatching required.
Supported Strategies
| Strategy | Example | Description |
|---|---|---|
subdomain |
tenant1.example.com |
Extracts tenant from subdomain |
path |
/tenant1/dashboard |
Extracts tenant from URL path segment |
header |
X-Tenant-ID: tenant1 |
Extracts tenant from HTTP header |
host |
client.com → tenant1 |
Maps full hostname to tenant |
chain |
Multiple strategies | Tries resolvers in order with fallback |
Quick Configuration
# config/packages/hakam_multi_tenancy.yaml hakam_multi_tenancy: resolver: enabled: true strategy: subdomain # subdomain | path | header | host | chain options: base_domain: 'example.com' # for subdomain strategy
Strategy Examples
Subdomain-based (e.g., acme.myapp.com):
resolver: enabled: true strategy: subdomain options: base_domain: 'myapp.com'
Header-based (for APIs):
resolver: enabled: true strategy: header options: header_name: 'X-Tenant-ID'
Path-based (e.g., /acme/dashboard):
resolver: enabled: true strategy: path excluded_paths: ['/api/public', '/health']
Chain strategy (fallback support):
resolver: enabled: true strategy: chain options: chain_order: [header, subdomain, path]
Accessing Resolved Tenant
The resolved tenant ID is available in request attributes:
// In a controller $tenantId = $request->attributes->get('_tenant');
Custom Resolver
Implement TenantResolverInterface for custom logic:
use Hakam\MultiTenancyBundle\Port\TenantResolverInterface; class CustomResolver implements TenantResolverInterface { public function resolve(Request $request): ?string { // Your custom logic return $request->cookies->get('tenant_id'); } public function supports(Request $request): bool { return $request->cookies->has('tenant_id'); } }
Note: Automatic resolution is disabled by default for backward compatibility. Manual
SwitchDbEventdispatching continues to work.
🚀 Quick Installation
1. Via Symfony Flex (Recommended)
composer require hakam/multi-tenancy-bundle
Symfony Flex will automatically scaffold config, register the bundle, and create:
src/Entity/Main/
src/Entity/Tenant/
migrations/Main/
migrations/Tenant/
2. Manual Installation
composer require hakam/multi-tenancy-bundle
Then register in config/bundles.php, copy the example hakam_multi_tenancy.yaml from docs, and create the required directories.
📖 Examples
The examples/ directory contains 15 ready-to-use code examples covering every feature of the bundle:
| # | Example | Feature |
|---|---|---|
| 01 | Entity Setup | TenantDbConfig entity with TenantDbConfigTrait |
| 02 | Bundle Configuration | Full YAML config reference |
| 03 | Tenant Entities | Tenant-scoped entities (Product, Order) |
| 04 | Database Lifecycle | Create DB, switch, CRUD, CLI commands |
| 05 | Tenant Migrations | Platform-agnostic migrations with Schema API |
| 06 | Resolvers | All 5 resolution strategies + controller usage |
| 07 | Lifecycle Events | All 6 events with subscriber pattern |
| 08 | Custom Config Provider | Redis, static, and in-memory providers |
| 09 | Tenant Fixtures | #[TenantFixture] attribute + CLI |
| 10 | Cache Isolation | TenantAwareCacheDecorator usage |
| 11 | Tenant Context | TenantContextInterface in services, Twig, listeners |
| 12 | Testing | TenantTestTrait with runInTenant() |
| 13 | Shared Entities | #[TenantShared] with exclusions |
| 14 | Custom Resolver | JWT, query param, API key resolvers |
| 15 | Full Onboarding Flow | Complete end-to-end tenant onboarding |
See also the Examples documentation page for detailed explanations.
🔗 Useful Links
- Full Documentation: [https://ramyhakam.github.io/multi_tenancy_bundle/]
- GitHub: https://github.com/RamyHakam/multi_tenancy_bundle
- Packagist: https://packagist.org/packages/hakam/multi-tenancy-bundle
- Example Project: https://github.com/RamyHakam/multi-tenancy-project-example
📄 License
MIT © Ramy Hakam