Multi tenancy with multiple database support
When reading the documentation, it appears that Filament only supports multi-tenancy with a single database by using
team_id
. Is implementing multiple databases in the plan, or is it easily achievable with a workaround, or do I need to use a third-party package like stancl/tenancy
or spatie/laravel-multitenancy
?32 Replies
Itβs not planned. Best to use a 3rd party plugin.
Hmm. I need this functionality as well. I do not see any plugins that support multi-database tenancy.
From searching the Discord chats here for Spatie Laravel-multitenancy, I see many problems, but none have a clear resolution.
I read an old (2022) GitHub post, but the methods they listed to get it to work don't seem to map to V3 since the configuration file structure is different. There may be more issues than that, but I decided to search more since the post is a couple of years old.
Has anyone gotten this to work?
Yes, I have multi-database tenancy using
stancl/tenancy
v4-alpha, but I guess v3 should work, too.@Dennis Koch that's great news. Do you remember the steps you took to get it working?
I see the liverwire integration section in the docs, just wondering if there were any gotchas
I think I was mostly following the docs. I read it 2 or 3 times because I missed some stuff. Only gotcha was manually symlinking tenants public folders.
Thanks for the heads up. I'll play around with this a bit later. I hadn't even looked at other laravel based packages besides Spatie
Most of the pain I went through was because this wasn't a fresh app, but we added tenancy later on π
Hi Dennis, great that you've got it working. I am suffering with stancl/tenancy and Filament at the moment. (I use Filament Form and Table separately).
In stancl/tenancy the config "asset_helper_tenancy" is set to true.
- Filament styles/scripts - Loaded from the wrong folder:
"@FilamentStyles and @FilamentScripts load files from the /tenancy/ folder, which does not work. (e.g.
"@FilamentStyles and @FilamentScripts load files from the /tenancy/ folder, which does not work. (e.g.
"/tenancy/assets/js/filament/support/async-alpine.js?v=3.2.80.0"
) - If I set asset_helper_tenancy
= false it works.
- FileUpload:
File uploads are not saved to the subfolder of the tenancy folder (e.g. /storage/tenantsport/
), so preview does not work.
The tenancy folder (public disk) is set by stancl/tenancy to /Development/valet/laravel-sites/filament-demo/storage/tenantsport/app/public/
, but files are saved to /Development/valet/laravel-sites/filament-demo/storage/app/public/
by the Filament FileUpload. It looks like Filament is not using the filesystems.disks.public.root configuration value when saving the file.
I hope you can give me some ideas on how to make it work.
Are there changes in v4-alpha, which makes it more easy to use stancl/tenancy and Filament together?Are there changes in v4-alpha, which makes it more easy to use stancl/tenancy and Filament together?They have public folder linking now, but it didn't work in ma case so I linked them manually π
Filament styles/scripts - Loaded from the wrong folder:I think you need to disable the
asset_helper_tenancy
.
File uploads are not saved to the subfolder of the tenancy folder (e.g. /storage/tenantsport/), so preview does not work.Did you set the Tenant middleware for the Livewire update route?
I am just curious the reasons for multiple databases with multi tenancy? Is it a requirement to just have data separate or are there other benefits?
@Dennis Koch Great tips. I used the two links below to set up "tenancy for laravel".
I still have a problem with the preview url in my Filament Form.
The uploaded files are correctly saved in the folder
/Development/valet/laravel-sites/filament-demo/storage/tenantsport/post/01HY2S9NP685FD3TFBCXRAF7RF.png
. Great.
The problem is that the preview in Filament is still loading from https://sport.my-site.test/storage/post/01HY2S9NP685FD3TFBCXRAF7RF.png
when it should be https://sport.my-site.test/storage/tenantsport/post/01HY2S9NP685FD3TFBCXRAF7RF.png
.
Do you have any idea what I am missing here?
Tenancy for Laravel - Livewire: https://tenancyforlaravel.com/docs/v3/integrations/livewire/#livewire
Tenancy for Laravel - Universal Routes: https://tenancyforlaravel.com/docs/v3/features/universal-routesThe problem is that the preview in Filament is still loading fromDid you configure your public disk in the
tenancy.public
config? Can you share that config?
In v4-alpha
it's called tenancy.filesystem.url_override
. Maybe that was introduced with v4These are my settings. Still using the v3.8.3 of stancl/tenancy.
'filesystem' => [
'suffix_base' => 'tenant',
'disks' => [
'local',
'public',
],
'root_override' => [
'local' => '%storage_path%/app/',
'public' => '%storage_path%/app/public/',
],
'suffix_storage_path' => true,
'asset_helper_tenancy' => false,
],
I guess there wasn't an option for that in v3 then.
Hm, I have to wait for the v4 release than.
Looks like symlinking the storage/tenant folders is also a challenge in v3.
artisan storage:link
does not work out of the box. Also this needs the tenancy.filesystem.url_override
parameter too in order to set the correct url, i guess.artisan storage:link
only does the central public folder. You can just manually symlink the others. That shouldn't be an issue.I made it work kind of. Works for a first test. Ideas to optimize it are welcome.
Tenant assets are now public available on
https://sport.my-site.test/tenant/post/123.png
I create the folders & public symlinks in CreateFrameworkDirectoriesForTenant
Added to...
In the custom route FileUrlMiddleware, i update the filesystems.disks.public.url
config value.
Thank you @camya! I've been working on this literally all day. Your middleware idea is solid solution and was exactly what I was missing.
Reading through https://discord.com/channels/883083792112300104/1180409835309764628 helped too for anyone trying to get Filament/Livewire/TenancyForLaravel working, but your solution is what solved it for me.
I use a ton of different disks to keep things organized, so instead of having a single public disk I use several that I've prefixed with 'tenant'
I need to refactor it, but all I have to do is just create a disk prefixed with 'tenant' and everything works with Tenancy, Filament v3 and Livewire. Of course follow the rest of the install/setup guide for tenancy regarding Livewire as well.
config/filesystem.php example
then my middleware grabs each disk and applies the proper url:
FileUrlMiddleware.php
And finally I added this to my TenancyServiceProvider to handle adding the tenant disks to the tenancy.php config (tenancy.filesystem.root_override and tenancy.filesystem.disks) automatically based on their names. I call this method in boot() fairly after setting middleware priority.
Edit: Fixed a hard-coded string that was causing problems. Should be more reliable.
I might have missed something. What were the other changes you had done apart from this to have stancl/tenancy work with filament?
Where exactly did you place this portion?
I used the FileUrlMiddleware in a few places.
One was in my tenant.php routes.
Another was in my TenantPortalPanelProvider.php
And finally this in my TenancyServiceProvider.php
Pretty much anywhere that needs to get a proper route to the tenants version of the file URLs.
I call this (method above) in my TenancyServiceProvider.php boot() method:
For me things were kind of working alright with just setting
tenancy.asset_helper_tenancy = false
as there were no tenant specific assets. Things fell apart when I had to add Import functionality.What kind of import functionality are you working with? CSV, or just uploads in general?
CSV uploads using importer action
This's gonna be nice one, with complicated work.
This is weird. After making all these changes, I can see the file upload issues getting solved, as in the fopen error went away. But for some reason the import and export jobs are failing now, as those are getting posted to central database. Although the corresponding actions (import/export) are posted to tenant database. The job ultimately fails after exceeding the number of attempts supported by the corresponding database field. File Exports were working last evening, but I hadn't committed the changes, as I wanted to do it right (via tenant folder).
And just like that it started working again π₯Ή
Seems I spoke too early. So now the import and exports jobs are working, but the export URL like
<subdomain>/filament/exports/1/download?format=csv
is giving me 404. And the path on disk looks a bit different. Notice filament_exports
in the folder path vis-a-vis filament/exports
in the URLDepending on the changes you made above, you might need to modify tenancy.php config. Double check your tenancy.filesystem.suffix_base, tenancy.filesystem.disks and finally tenancy.filesystem.root_override. I try to do this in my setupTenantDisks() method above, but you can do it manually just as easily if you dont have too many disks.
That's the first place I would check if tenant files are ending up in the base public directory.
Actually the files are landing correctly in the tenant specific folder, as can be seen in the screenshot above. I think somehow the
/filament/exports
route is looking at the wrong place, probably the root public folder instead of tenant specific public folder
Looks like the filament.exports
route itself is throwing 404, as in action corresponding to the route not found from inside tenant application
I am unable to figure out these 404. Has anyone else faced such an issue?It dose not work with me
see the url is not work
Thank you for this awesome solution! Your work is truly excellent and creative>
@CGM Many thanks for your help ! Works like a charm!