Courses

Laravel 12 Multi-Tenancy: All You Need To Know

Quick Run Through More Extra Features

Summary of this lesson:
- Separating tenant cache and storage systems
- Implementing tenant-aware testing
- Integrating multi-tenancy with third-party packages

Finally, in the last lesson of this section, I will quickly run through other features of this package.


So, what can you separate databases for different tenants, what else can you separate? For example, you can separate the cache. If you use a cache driver with tags like Redis, you can separate the tags and clear the cache of certain tenants.


Then, a complex file system tenancy bootstrapper enables tenants to separate storage or assets. And, as it is said in the official documentation, this bootstrapper is the most complex one by far because it has a lot of logic on how to separate by subfolders.

What it does is separate the files. For example, if I store that in the path of tasks, it separates create storage/app. Instead of storage/app, it has storage/{tenant_id}/app, and each tenant has its subfolder with storage inside.

Then, you could separate the tenant and, for example, backup only that tenant's files if needed.


Also, this package allows testing to be tenantable. For example, you can run the test on the tenant app. On the setUp(), you need to initialize tenancy.

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
 
abstract class TestCase extends BaseTestCase
{
protected $tenancy = false;
 
public function setUp(): void
{
parent::setUp();
 
if ($this->tenancy) {
$this->initializeTenancy();
}
}
 
public function initializeTenancy()
{
$tenant = Tenant::create();
 
tenancy()->initialize($tenant);
}
}

And then, in your test cases, you can set the $tenancy property to true. That is quite helpful.

class FooTest extends TestCase
{
protected $tenancy = true;
 
/** @test */
public function some_test()
{
$this->assertTrue(...);
}
}

Finally, I want to mention the integration with other packages. Generally, if you dive deeper into multi-tenancy and then add more functionality, every new feature needs to be aware of the tenant: which tenant to work with, which database to work with, where to get assets from or storage file or something else or cache or queues.

So, all the external packages don't know about your multi-tenancy. For some packages, the tenancy package advises how to get them to work together. For example, for spatie/laravel-activitylog you need to change some config.

For spatie/laravel-permission, you need to create the permission tables, move them from database/migrations to database/migrations/tenant, so they would be created in each of the tenants separately.

That is the logic for more packages because then you need to move the migrations into the tenant and migrate in each database separately.

There are more packages mentioned here, such as Passport, Nova, and others. Generally, if you go the complex route of multi-database multi-tenancy, it opens up a deep rabbit hole, Pandora's box, or whatever you call it.

And with each new functionality, you need to be aware of tenants, databases, subdomains, etc.


For now, for this course, you've got the basics of what you need to know: how multi-tenancy works, how to set it up, and how to configure it. From here, it's a matter of your fantasy and skills to apply to your projects.

Good luck with that. And see you guys in other lessons!

avatar

Very good content. Thank you!

avatar
You can use Markdown
avatar

hi can you point me to some documentation or project resource for advance multitenancy more intertested in S3 bucket seperation, passport integration users/devices, Firebase Messeging / AWS SNS.

thanks in advance rahul

avatar

i would love to see any advance tennancy courses from you specially on tennency for laravel.

avatar

Well, it should be all in the documentation of the packages that I discussed.

Quote from stancl/tenancy docs: https://tenancyforlaravel.com/docs/v3/tenancy-bootstrappers/

Note: If you want to bootstrap filesystem tenancy differently (e.g. provision an S3 bucket for each tenant), you can absolutely do that. Take a look at the package's bootstrappers to get an idea of how to write one yourself, and feel free to implement it any way you want.

Personally I didn't work with Passport integration or Firebase messaging, so I can't advise on those.

avatar
You can use Markdown
avatar

Hello,

The course is extremely helpful. Thank you. Can you help in directing me to a source code or a documentation to how we can go deep in using multi-tenancy multiple DB along with laravel modules and permissions?

Thank you.

avatar

I don't have any more documentations or source for you than the packages provide, so you should re-read the docs of the package of your choice, and then practice everything else yourself. Not everything has a ready-made tutorial, unfortunately.

avatar
You can use Markdown
avatar

This has been a great course Povilas! As stated by @Karbahs, User permissions/roles seem to be a standard feature that is not addressed, a User that has multiple tenants but with different permissions/roles in each tenant.

For example, User_A is an owner/admin of Tenant_1 but only a member of Tenant_2.

I have been reading in great detail this situation and here is a good thread to read regarding this: https://github.com/archtechx/tenancy/issues/57

avatar
You can use Markdown
avatar

Thanks for this nice course, Povilas! It has given me a good understanding of Multi-Tenancy.

I would like to see an advanced Multi-Tenancy course, where you dive deeper into some more complicated stuff.

avatar
You can use Markdown
avatar

Very nice course, thank you. I would like to see testing with multi tenancy espically with muti database setups.

avatar

For now not in plans, sorry, it's too niche topic for quite a small percentage of developers who actually need it. For now, I'm focused on the topic for broader audience.

avatar
You can use Markdown
avatar

That's a great content!!!

It would be good to see another course, talking about Multi-Tenancy with a Hybrid Archtecture. Something that could use separate DBs or multiple schema at the same DB. Even with the possibility of managing how the bank should be created and perhaps a way to move a large schema into a separate instance. Dreaming costs nothing and does no harm... LOL

A whole world really opens up when we look into this subject.

Thank you.

avatar
You can use Markdown
avatar
Shadyar Bzhar Othman

Thanks for this course. You didn't discuss what changes if you're using it with an API, like a Vue SPA, with the package. Also, what's the best way to identify a tenant? Should you send the subdomain with every request, or is there another recommended approach?

If you can provide some explanation, I'd appreciate it.

avatar

This tutorial was not meant for an API example, so it excluded API things. But they are pretty much the same if I'm being honest.

The best way to identify a tenant is to have a middleware that parses a request parameter/header/whatever you agree upon. And yes, this has to be sent with the request in order to direct to a specific tenant. Otherwise, there is nobody to identify with :)

avatar
Shadyar Bzhar Othman

Thank you very much!

I must send the domain or sub domain with every requerst or what because as I read in tyeh docs about Request data identification which is recommanded for api it need X-Tenant which I think teh tenant id, so I need to request to teh backend to getthis domain's tenant id then get the request

I think I'm wrong with that but I couldn't find anything else, thank you!

avatar

It really depends. If your subdomains are unique and you don't have a whitelabel - you can always just send the subdomain OR get a UUID from the domain and send it back (this prevents users from guessing the "token" of the domain by entering a company name OR id like "142516").

However, it does not matter if you send X-Tenant (also remember, that X- is not required anymore!) or if you send Tenant-domain and Tenant-UUID (for double match). Pick whichever works for you and stay consistent :)

avatar
Shadyar Bzhar Othman

Thank you very much!

avatar
You can use Markdown
avatar

Hey there, I have set up the multi tenant multi db boilerplate and now want to intergrate Lunarphp, any pointers on how to go about it?

avatar
You can use Markdown
avatar
You can use Markdown