Overview of Laravel Multi Domain
master.env files).repository·master·Indexed 22 days ago
https://github.com/gecche/laravel-multidomainAn extension that allows a single Laravel codebase to serve multiple HTTP domains with tenant isolation for databases, storage paths, and environment configurations. It provides domain-specific .env files, isolated storage directories, and custom configuration merging. Compatible with Laravel 5.x through 13.x, it includes Artisan commands for domain management (domain:add, domain:remove, domain:list) and supports domain-aware queue workers and configuration caching.
.env files).To install the package, add it to your composer.json and run composer update or composer install.
Note for Laravel 11+: The installation process is simpler than for previous versions. The following steps apply to older Laravel versions.
{
"require": {
"gecche/laravel-multidomain": "13.*
}
}If you use Laravel Horizon, you must replace the Horizon import in your app/Providers/HorizonServiceProvider.php file with the package's version.
// app/Providers/HorizonServiceProvider.php
//use Laravel\Horizon\HorizonApplicationServiceProvider;
use Gecche\Multidomain\Horizon\HorizonApplicationServiceProvider;For Laravel versions prior to 11, you must perform manual configuration to allow the package to override domain detection and service providers.
bootstrap/app.php, replace the standard Laravel Application import with the Gecche version.config/app.php, use the replace method on the providers array to swap the standard QueueServiceProvider with the package's version.php artisan vendor:publish to publish the package configuration.// 1. In bootstrap/app.php
//use Illuminate
use Gecche//Multidomain//Foundation//Application
// 2. In config/app.php
'providers' => \Illuminate\Support\ServiceProvider::defaultProviders()->merge([
// Package Service Providers...
])->replace([
\Illuminate\Queue\QueueServiceProvider::class => \Gecche\Multidomain\Queue\QueueServiceProvider::class,
])->merge([
// Added Service Providers (Do not remove this line)...
])->toArray(),To ensure commands use the correct environment and storage settings, use the --domain option.
php artisan list --domain=site1.comphp artisan queue:work --domain=site1.comImportant for Queues: If domains share a database driver, use distinct queues for each domain to prevent job cross-contamination. You can define a domain-specific queue in your .env file (e.g., QUEUE_DEFAULT=default1) and reference it in config/queue.php using env('QUEUE_DEFAULT', 'default').
php artisan queue:work --domain=site1.com --queue=default1You can provide domain-specific configuration files by placing them in config/domains/. The filename must be the sanitized domain name (dots replaced with underscores).
Example for site1.com: config/domains/site1_com.php.
These values are merged recursively into the standard Laravel configuration. When running php artisan config:cache --domain=site1.com, the cached file will include these merged values.
// config/domains/site1_com.php
return [
'app' => [
'name' => 'Site 1 Application',
],
];The Gecche\Multidomain\Foundation\Console\Kernel extends the standard Laravel Console Kernel but modifies the bootstrapping process to support multi-tenancy/multi-domain logic.
It injects two critical custom bootstrappers into the application lifecycle:
\Gecche\Multidomain\Foundation\Bootstrap\DetectDomain::class: Identifies which domain is being targeted.\Gecche\Multidomain\Foundation\Bootstrap\LoadDomainConfiguration::class: Loads the configuration specific to the detected domain.This ensures that when a command is run, the environment and configuration are correctly scoped to the requested domain.
To customize your domain settings, you can publish the package's configuration file to your application's config directory. This allows you to manage the domain.php configuration file locally.
php artisan vendor:publish --tag=configInstead of the standard Laravel application instantiation, use the configure static method on Gecche\Multidomain\Foundation\Application. This method returns an ApplicationBuilder which allows you to fluently register kernels, events, commands, and providers specifically for a multi-domain setup.
Supported parameters for configure:
$basePath (string|null): The base path of the application.$environmentPath (string|null): The path to the environment files.$domainParams (array): Miscellaneous parameters for domain handling (e.g., custom domain detection functions).use Gecche\Multidomain\Foundation\Application;
$app = Application::configure(
$basePath,
$environmentPath,
['domain_detection_function_web' => $myCustomClosure]
)
->withKernels()
->withEvents()
->withCommands()
->withProviders();By default, .env files are stored in the Laravel root directory. To store them in a custom folder (e.g., envs/), pass the path as the second argument to the Application constructor in bootstrap/app.php.
Note: If you use a custom folder, the standard .env file must also be moved into that folder.
// bootstrap/app.php
$environmentPath = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'envs';
return Application::configure(basePath: dirname(__DIR__), environmentPath: $environmentPath)
// ...
->create();At runtime, the current HTTP domain is available in the Laravel container. You can access it via the domain() method or retrieve all domain information using the domainList() method.
domainList() returns an associative array where keys are domain names and values contain storage_path and env.
// Get current domain
$currentDomain = app()->domain();
// Get all domains info
$domains = app()->domainList();
/*
[
'site1.com' => [
'storage_path' => '/path/to/storage/site1_com',
'env' => '.env.site1.com'
]
]
*/The package defaults to using $_SERVER['SERVER_NAME'] to detect the domain. If your environment uses a different variable (like $_SERVER['HTTP_HOST']), you can customize this by passing a Closure to the domain_detection_function_web key within the domainParams array in the Application constructor.
// bootstrap/app.php
$domainParams = [
'domain_detection_function_web' => function() {
return \Illuminate\Support\Arr::get($_SERVER, 'HTTP_HOST');
}
];
return Application::configure(basePath: dirname(__DIR__), domainParams: $domainParams)
// ...
->create();