socialdept / tenant-domains
Custom domains for multi-tenant Laravel apps: ownership, DNS instructions, ACME delegation and certificates
Requires
- php: ^8.3
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- jeremykendall/php-domain-parser: ^6.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.89
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^11.0|^12.0
- stancl/tenancy: ^3.9
Suggests
- stancl/tenancy: Required for the packaged Domain model and tenant resolution (^3.9)
Provides
None
Conflicts
None
Replaces
None
README
Custom domains for multi-tenant Laravel apps. Cloudflare for SaaS, without Cloudflare for SaaS.
This package lets the tenants of a Laravel app bring their own domain. It proves they own it, tells them the exact records to create in the form their DNS provider expects, gets a certificate through an _acme-challenge delegation without touching their zone, tells your Caddy edge to serve it, and then makes a real request to prove traffic lands on your origin. To learn all about it, head over to the documentation.
Here are a few short examples of what you can do. Check what a tenant typed before storing anything:
use SocialDept\TenantDomains\Facades\TenantDomains; $check = TenantDomains::inspect('www.example.co.uk'); $check->domain; // 'example.co.uk', the row to create $check->www->supported; // true, so ask the tenant about www
Get the records the tenant has to create:
TenantDomains::ensureDelegationId($domain); $instructions = TenantDomains::instructionsFor($domain); $instructions->record('ownership'); // TXT _verify.blog verification=… $instructions->record('acme'); // CNAME _acme-challenge.blog k7m2q4bdhxwz.acme.yourapp.com
Verify the domain and hand it to the edge:
if (TenantDomains::verifyOwnership($domain) && TenantDomains::verifyRouting($domain)->verified) { TenantDomains::publish($domain); }
Or let the reconciler finish setup once the tenant's DNS has propagated:
Schedule::command('domains:reconcile')->everyFiveMinutes();
Documentation
You'll find the documentation on https://socialde.pt/docs/tenant-domains.
Find yourself stuck using the package? Found a bug? Do you have general questions or suggestions for improving it? Feel free to create an issue on GitHub.
Testing
vendor/bin/phpunit
Contributing
Please see CONTRIBUTING for details.
License
The MIT License (MIT). Please see LICENSE for more information.