- How do I set up Laravel MultiDomain for a SaaS app with separate databases per tenant?
- First, install the package via Composer (`gecche/laravel-multidomain`). Then, create a `.env.site1.com` file for each tenant with their DB credentials. The package automatically loads the correct `.env` based on the domain (e.g., `site1.example.com`). Ensure your `config/domains.php` lists allowed domains, and configure your web server to route subdomains to the Laravel app.
- Can I use this package with Laravel 13, or do I need a specific version?
- Yes, Laravel MultiDomain supports Laravel 13.x with its latest releases. Always check the [compatibility table](https://github.com/gecche/laravel-multidomain#version-compatibility) to match your Laravel version with the correct package version. For Laravel 13, use the `13.x` branch or the latest stable release.
- How do I configure tenant-specific storage paths (e.g., `storage/site1_com`)?
- The package dynamically resolves storage paths to `storage/{domain}/`. For example, `site1.example.com` uses `storage/site1_com/`. You must manually create these directories and set proper permissions (e.g., `chown -R www-data:www-data storage/site1_com`). Use `php artisan storage:link --domain=site1.com` to create symlinks for public assets.
- Does this package support queue isolation for tenants (e.g., separate Redis queues)?
- Yes, but you must configure it manually. Define `QUEUE_CONNECTION=redis` and `QUEUE_DEFAULT=site1_jobs` in `.env.site1.com`. The package respects these settings per tenant. For database queues, ensure `QUEUE_TABLE` is unique per tenant or use separate queue tables. Redis/SQS isolation requires separate instances or queue names.
- Will this work with Laravel Forge/Envoyer, or do I need to modify their bootstrapping?
- The package requires modifying `bootstrap/app.php` to load the multi-domain logic early. Forge/Envoyer users may need to adjust their deployment scripts to include this change. Test thoroughly, as future Laravel updates could alter `app.php` structure. Document the override in your deployment notes.
- How do I handle CLI commands for specific tenants (e.g., `php artisan migrate --domain=site1.com`)?
- The package adds `--domain` flags to Artisan commands. Run `php artisan --domain=site1.com migrate` to target a tenant’s database. For queues, use `php artisan queue:work --domain=site1.com`. Ensure your `.env.site1.com` has the correct DB credentials. This works for most Artisan commands.
- Can I use this for wildcard subdomains (e.g., `*.example.com`) without conflicts?
- Wildcard subdomains may conflict with Laravel’s routing. Explicitly list allowed domains in `config/domains.php` and use middleware to validate domains. Avoid relying on wildcard DNS for tenant isolation, as the package requires exact domain matches to load the correct `.env` file.
- What’s the performance impact of loading per-domain `.env` files on every request?
- Loading a `.env` file per request adds minor overhead, but it’s negligible for most applications. To optimize, cache configs with `php artisan config:cache --domain=site1.com`. Avoid caching if tenants frequently update their `.env` files. Test under load to ensure your server can handle the additional I/O.
- How do I integrate this with Laravel Horizon for tenant-specific queues?
- Horizon requires a one-line override in `HorizonServiceProvider`. Add `$this->app->bind('queue.connection', function () { return app('queue')->connection(); });` to your provider. Configure `QUEUE_CONNECTION` and `QUEUE_DEFAULT` in each tenant’s `.env` file. Horizon will then use the correct queue connection per domain.
- Are there alternatives like stancl/tenancy that offer database schema isolation instead?
- Yes, `stancl/tenancy` provides schema-based multi-tenancy (shared DB with tenant schemas), while this package isolates tenants via separate databases, storage, and `.env` files. Choose this package if you need full isolation (e.g., SaaS with strict compliance) or `stancl/tenancy` if you prefer a shared database with tenant IDs. Both integrate with Laravel but solve different problems.