Laravel Multi Domain

repository·master·Indexed 22 days ago

https://github.com/gecche/laravel-multidomain

An 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.

Tokens
6.9K
Snippets
27
Records
33
Agent score
78%

What's inside gecche/laravel-multidomain

  1. Overview of Laravel Multi Domain

    master
    Laravel Multi Domain is an extension that enables a single Laravel installation to operate across multiple HTTP domains. It is designed for scenarios where different customers or tenants share the same application code but require isolated environments for their databases, storage paths, and configuration files (via specific .env files).
  2. Install gecche/laravel-multidomain

    master

    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.*
        }
    }
  3. Install Laravel Horizon with Multi-Domain support

    master

    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;
  4. Configure Laravel for Multi-Domain support (Legacy Laravel)

    master

    For Laravel versions prior to 11, you must perform manual configuration to allow the package to override domain detection and service providers.

    1. Replace the Application class: At the very top of bootstrap/app.php, replace the standard Laravel Application import with the Gecche version.
    2. Override QueueServiceProvider: In config/app.php, use the replace method on the providers array to swap the standard QueueServiceProvider with the package's version.
    3. Publish Configuration: Run 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(),
  5. Run Artisan and Queue commands for specific domains

    master

    To ensure commands use the correct environment and storage settings, use the --domain option.

    • General Artisan commands: php artisan list --domain=site1.com
    • Queue workers: php artisan queue:work --domain=site1.com

    Important 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=default1
  6. Use domain-specific configuration files

    master

    You 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',
        ],
    ];
  7. How the multi-domain console kernel bootstraps

    master

    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:

    1. \Gecche\Multidomain\Foundation\Bootstrap\DetectDomain::class: Identifies which domain is being targeted.
    2. \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.

  8. Bootstrap a multi-domain Laravel application

    master

    Instead 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();
  9. Configure custom environment file location

    master

    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();
  10. Access current domain information in code

    master

    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'
        ]
    ]
    */
  11. Customize HTTP domain detection

    master

    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();