Skip to main content

archtechx / tenancy: Installation, Configuration and Register Tenant

Premium
8:12

The next package we will check is stancl/tenancy. With this package, you can have single and multi-database tenancy. First, we will take a look at a single database approach.

The starting point is the same CRUD with the Project and Task without any tenancy.


Installation and Configuration

So, first, install the package via composer and then run the tenancy:install command.

composer require stancl/tenancy
php artisan tenancy:install
php artisan migrate

Next, we must add the TenancyServiceProvider.

bootstrap/providers.php:

return [
App\Providers\AppServiceProvider::class,
App\Providers\TenancyServiceProvider::class,
];

Install command created the Migration for the tenants table. Now we must make a Model for that table and replace the content of the Model with the code from the quickstart.

php artisan make:model Tenant

app/Models/Tenant.php:

namespace App\Models;
 
use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
use Stancl\Tenancy\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\Concerns\HasDatabase;
use Stancl\Tenancy\Database\Concerns\HasDomains;
 
class Tenant extends BaseTenant implements TenantWithDatabase
{
use HasDatabase, HasDomains;
}

Next, in the config/tenancy.php, we need to set that package to use...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (30 h 50 min)

You also get:

55 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

K
kiogo ✓ Link copied!

Are there any major advantages to archtechx/tenancy compared to the team multi-tenancy no package solution?

M
Modestas ✓ Link copied!

As with everything in code - we can't say that one is better than another.

Tenancy has the biggest advantage of being public and used by many, which means it should be relatively bug free. While your custom solution is fresh and might have bugs.

Which is better? Can't tell! This has to be tried and looked at case-by-case (for example, in my projects - I constantly switch between similar packages as they usually offer some key differences)

K
kfs ✓ Link copied!

what if a team or a user wants to have a diffrent domain, is it possible to have different domains for each tenant

M
Modestas ✓ Link copied!

It's possible for sure, but that comes with complications.

You need a devops to create a proxy server OR you need to configure your own server to issue correct SSL certificates on top. Then, there is a big logic change oh how your application recognizes the domain and uses it. You have to use https://laravel.com/docs/11.x/routing#route-group-subdomain-routing but instead of subdomain, you have to add full domain and store full domains in database.

From there, it in theory works, but you have to do EXTENSIVE testing :)

K
kfs ✓ Link copied!

what if its type a like cloudflare type a domain it takes the host ip only wont it work ?

M
Modestas ✓ Link copied!

No, that's not how it works. If you do a host ip only - you will have to always type the IP to access the tenant.

Keep in mind:

Domain is just a human friendly IP. Seriously, you can access your website via an IP, but domain is just a human friendly version in the URL.

SB
Shadyar Bzhar Othman ✓ Link copied!

What's the different between these?

// ...
 
protected function mapRoutes()
{
if (file_exists(base_path('routes/tenant.php'))) {
Route::namespace(static::$controllerNamespace)
->group(base_path('routes/tenant.php'));
}
 
$this->app->booted(function () {
if (file_exists(base_path('routes/tenant.php'))) {
Route::namespace(static::$controllerNamespace)
->group(base_path('routes/tenant.php'));
}
});
}
 
// ...

What does this mean? [tl! add:start]

M
Modestas ✓ Link copied!

Hi,

The first one just adds routes, but it can cause some problems. That's why on the second example it is wrapped with $this->app->booted(). This prevents issues from appearing.

As for [tl! add:start] - ignore it! This is torchlight malfunctioning (our code highligher) :)

SB
Shadyar Bzhar Othman ✓ Link copied!

Thanks!

M
M ✓ Link copied!

I struggled a bit trying to get the login redirecting to the subdomain using Laravel v12 Livewire Volt starter kit. There is probably an easier way to manually get a user's recent/cached domain but I wasn't able to find it. Any tips?

With the default login it was showing a 404 error as it is redirecting to the central domain's dashboard instead of the subdomain's dashboard.

$domain = auth()->user()->tenants()->firstOrFail()->domains()->firstOrFail()->domain;
 
// $this->redirectIntended(default: route('dashboard', absolute: false), navigate: true);
$this->redirect('//' . Str::of($domain)->rtrim('/') . route('dashboard', absolute: false));

I'm simply picking out the user's first tenant with it's first domain. Moving on.

M
Modestas ✓ Link copied!

To be fair, this looks like reasonable code. Not sure if it could be improved by a lot (maybe the redirect part, but if it works - it works) :)

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.