Help with Tenancy With Laravel Package

guys i need help with setting up multi database architecture using tenancy with Laravel package, if you can provide a full guide for setting up database.php , tenancy.php and .env connection i would highly appreciate it
Solution:
thanks for @Geoff. and his efforts we managed to make a gist with a full guide to implement multi-tenancy with multiple database approach here is the link for the gist https://gist.github.com/Hegabovic/81d63f16dcceac16ecbdd0c3722857ae now we can close this question as resolved ✅...
Gist
Full Guide for Multi-tenancy with tenancy with laravel package
Full Guide for Multi-tenancy with tenancy with laravel package - multi-tenancy.md
Jump to solution
66 Replies
Lara Zeus
Lara Zeus13mo ago
never had to setup multi database but its all in the midelwear this may help https://discord.com/channels/883083792112300104/1152246454581219388
Hegabovic
HegabovicOP13mo ago
i was ther ebut i still need some help
awcodes
awcodes13mo ago
Start with following the package you are using’s setup instructions. Then comeback to Filament. You’re getting into a pretty complicated thing and you’ll need a solid understanding of this type of tenancy before even worrying about making it work with filament.
Hegabovic
HegabovicOP13mo ago
actually i understand it pretty good, but the thing is there is no configuration guide for it
awcodes
awcodes13mo ago
Wish I could help more. But it’s just not my strong suit.
Hegabovic
HegabovicOP13mo ago
thanks a lot for even trying to help 😄 i really appreciate it 😄
Hegabovic
HegabovicOP13mo ago
i finally managed to make it work but the design are not loaded even if i ran npm run dev or npm run build
No description
Lara Zeus
Lara Zeus13mo ago
check the console for errors make sure the app_url in env file is currect
Hegabovic
HegabovicOP13mo ago
but idk what is that !
No description
Lara Zeus
Lara Zeus13mo ago
in .env file check APP_URL=https://site.test
Hegabovic
HegabovicOP13mo ago
it is the APP_URL=http://localhost:8000
Lara Zeus
Lara Zeus13mo ago
not sure how tenancy package will handle the vendor assets check the Assets section here https://tenancyforlaravel.com/docs/v3/tenancy-bootstrappers/#filesystem-tenancy-boostrapper
Tenancy for Laravel
Tenancy bootstrappers | Tenancy for Laravel
Tenancy bootstrappers | Tenancy for Laravel
Lara Zeus
Lara Zeus13mo ago
also Configuring the asset URL (ASSET_URL in your .env) for me I recommend disable tenancy of asset() unless you absolutely need it
Hegabovic
HegabovicOP13mo ago
ok i will look into it , thanks a lot 😄
Geoff.
Geoff.13mo ago
setting
'asset_helper_tenancy' => false
'asset_helper_tenancy' => false
helped for me
Hegabovic
HegabovicOP13mo ago
yeah i actually worked perfectly , the only issue i have now is the main site which is localhost:8000 is giving me that error and i cant access it
No description
Geoff.
Geoff.13mo ago
did you set your central domain
Hegabovic
HegabovicOP13mo ago
yup to localhost
Hegabovic
HegabovicOP13mo ago
No description
Geoff.
Geoff.13mo ago
you also have the routes and stuff?
Hegabovic
HegabovicOP13mo ago
in the web.php i put the default laravel view , but it gets me the error i provided before
Geoff.
Geoff.13mo ago
Tenancy for Laravel
Installation | Tenancy for Laravel
Installation | Tenancy for Laravel
Hegabovic
HegabovicOP13mo ago
yup word bu word , letter by letter 😄
Geoff.
Geoff.13mo ago
Can you show me your routeserviceprovider
Hegabovic
HegabovicOP13mo ago
<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
/**
* The path to your application's "home" route.
*
* Typically, users are redirected here after authentication.
*
* @var string
*/
public const HOME = '/home';

/**
* Define your route model bindings, pattern filters, and other route configuration.
*/
public function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});



$this->routes(function () {
$this->mapApiRoutes();
$this->mapWebRoutes();
});
}
protected function mapWebRoutes()
{
foreach ($this->centralDomains() as $domain) {
Route::middleware('web')
->domain($domain)
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
}

protected function mapApiRoutes()
{
foreach ($this->centralDomains() as $domain) {
Route::prefix('api')
->domain($domain)
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}

protected function centralDomains(): array
{
return config('tenancy.central_domains');
}
}
<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
/**
* The path to your application's "home" route.
*
* Typically, users are redirected here after authentication.
*
* @var string
*/
public const HOME = '/home';

/**
* Define your route model bindings, pattern filters, and other route configuration.
*/
public function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});



$this->routes(function () {
$this->mapApiRoutes();
$this->mapWebRoutes();
});
}
protected function mapWebRoutes()
{
foreach ($this->centralDomains() as $domain) {
Route::middleware('web')
->domain($domain)
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
}

protected function mapApiRoutes()
{
foreach ($this->centralDomains() as $domain) {
Route::prefix('api')
->domain($domain)
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}

protected function centralDomains(): array
{
return config('tenancy.central_domains');
}
}
Geoff.
Geoff.13mo ago
hmm did you add te InitializeTenancyByDomain::class provider to your panel?
Hegabovic
HegabovicOP13mo ago
no i can't find it in my panel but what is it , and where to put it there ? and should i put it in every panel ?
Geoff.
Geoff.13mo ago
Are you trying to have multiple db's per tenant?
Hegabovic
HegabovicOP13mo ago
yes each tenant will have his own database and it is working in the subdomains level (tenants) , the remaining problem now is with the main site (the place i will be using for making domains)
Geoff.
Geoff.13mo ago
so you will have an admin panel where you can see all the tenants with their own database and you will have a tenant/app panel for each tenant
Hegabovic
HegabovicOP13mo ago
yup i want to do that exactly
Geoff.
Geoff.13mo ago
did you already made a panel with artisan make:filament-panel ?
Hegabovic
HegabovicOP13mo ago
yup i have admin panel yes
Hegabovic
HegabovicOP13mo ago
No description
Geoff.
Geoff.13mo ago
can you show me the content of it
Hegabovic
HegabovicOP13mo ago
sure thing
<?php

namespace App\Providers\Filament;

use Filament\Panel;
use Filament\Pages;
use Filament\Widgets;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Awcodes\LightSwitch\Enums\Alignment;
use Jeffgreco13\FilamentBreezy\BreezyCore;
use Awcodes\LightSwitch\LightSwitchPlugin;
use Filament\Http\Middleware\Authenticate;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Routing\Middleware\SubstituteBindings;
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Hegabovic\UserManagement\Http\Middleware\CheckActiveUser;
use Hegabovic\FilamentUserManagement\Http\Middleware\RedirectFilament;

class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('users')
->path('users')
->login()
->passwordReset()
->sidebarCollapsibleOnDesktop()
->colors([
'primary' => Color::Amber,
])
->navigationGroups([
// FilamentSettingsManagementConstants::NAVIGATION_GROUP_SETTINGS,
'system'
])

// ->brandLogo()
->plugins([
// ThemesPlugin::make(),
// FilamentRouteStatisticsPlugin::make(),
<?php

namespace App\Providers\Filament;

use Filament\Panel;
use Filament\Pages;
use Filament\Widgets;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Awcodes\LightSwitch\Enums\Alignment;
use Jeffgreco13\FilamentBreezy\BreezyCore;
use Awcodes\LightSwitch\LightSwitchPlugin;
use Filament\Http\Middleware\Authenticate;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Routing\Middleware\SubstituteBindings;
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Hegabovic\UserManagement\Http\Middleware\CheckActiveUser;
use Hegabovic\FilamentUserManagement\Http\Middleware\RedirectFilament;

class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('users')
->path('users')
->login()
->passwordReset()
->sidebarCollapsibleOnDesktop()
->colors([
'primary' => Color::Amber,
])
->navigationGroups([
// FilamentSettingsManagementConstants::NAVIGATION_GROUP_SETTINGS,
'system'
])

// ->brandLogo()
->plugins([
// ThemesPlugin::make(),
// FilamentRouteStatisticsPlugin::make(),
LightSwitchPlugin::make()
->position(Alignment::TopLeft)
->enabledOn(['auth.login']),
FilamentShieldPlugin::make(),
BreezyCore::make()
->myProfile(
shouldRegisterUserMenu: true, // Sets the 'account' link in the panel User Menu (default = true)
shouldRegisterNavigation: false, // Adds a main navigation item for the My Profile page (default = false)
hasAvatars: true, // Enables the avatar upload form component (default = false)
slug: 'my-profile' // Sets the slug for the profile page (default = 'my-profile')
),
])
->plugins(config("filament-poeditor-config.plugins"))
LightSwitchPlugin::make()
->position(Alignment::TopLeft)
->enabledOn(['auth.login']),
FilamentShieldPlugin::make(),
BreezyCore::make()
->myProfile(
shouldRegisterUserMenu: true, // Sets the 'account' link in the panel User Menu (default = true)
shouldRegisterNavigation: false, // Adds a main navigation item for the My Profile page (default = false)
hasAvatars: true, // Enables the avatar upload form component (default = false)
slug: 'my-profile' // Sets the slug for the profile page (default = 'my-profile')
),
])
->plugins(config("filament-poeditor-config.plugins"))
->resources(config("filament-settings-management-config.resources"))
->resources(config("filament-user-management-config.resources"))

->pages([Pages\Dashboard::class,],)
->pages(config("filament-poeditor-config.pages"))
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')

->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->widgets([
Widgets\AccountWidget::class,
Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
CheckActiveUser::class,
RedirectFilament::class,

// SetTheme::class
])
// ->tenantMiddleware([
// \Hasnayeen\Themes\Http\Middleware\SetTheme::class
// ])
->authMiddleware([
Authenticate::class,
]);
}
}
->resources(config("filament-settings-management-config.resources"))
->resources(config("filament-user-management-config.resources"))

->pages([Pages\Dashboard::class,],)
->pages(config("filament-poeditor-config.pages"))
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')

->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->widgets([
Widgets\AccountWidget::class,
Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
CheckActiveUser::class,
RedirectFilament::class,

// SetTheme::class
])
// ->tenantMiddleware([
// \Hasnayeen\Themes\Http\Middleware\SetTheme::class
// ])
->authMiddleware([
Authenticate::class,
]);
}
}
Geoff.
Geoff.13mo ago
could you try without all the plugins? and what is the redirectfilament middleware doing
Hegabovic
HegabovicOP13mo ago
its for the redirection if you are not authorized to visit a specfic route (return to login page) still the same , the thing is that the app doesn't see the / of the main site anymore
Geoff.
Geoff.13mo ago
did you try to clear cache already
Hegabovic
HegabovicOP13mo ago
yup , and nothing happened even on another browser there is the subdomain
Hegabovic
HegabovicOP13mo ago
No description
Hegabovic
HegabovicOP13mo ago
and there is the localhost:8000
Hegabovic
HegabovicOP13mo ago
No description
Geoff.
Geoff.13mo ago
But I mean the cache of laravel itself
Hegabovic
HegabovicOP13mo ago
yes php artisan optimize:clear , yeah i did it
Geoff.
Geoff.13mo ago
i messaged you on discord
Solution
Hegabovic
Hegabovic13mo ago
thanks for @Geoff. and his efforts we managed to make a gist with a full guide to implement multi-tenancy with multiple database approach here is the link for the gist https://gist.github.com/Hegabovic/81d63f16dcceac16ecbdd0c3722857ae now we can close this question as resolved ✅
Gist
Full Guide for Multi-tenancy with tenancy with laravel package
Full Guide for Multi-tenancy with tenancy with laravel package - multi-tenancy.md
awcodes
awcodes13mo ago
Great job guys. This could be a great article on the Filament site. I encourage you to submit it. https://github.com/filamentphp/filamentphp.com#submitting-an-article-to-the-community-section
GitHub
GitHub - filamentphp/filamentphp.com: Source code for the filamentp...
Source code for the filamentphp.com website. Contribute to filamentphp/filamentphp.com development by creating an account on GitHub.
Hegabovic
HegabovicOP13mo ago
if i can share it there , i will do it now 😄
awcodes
awcodes13mo ago
Please do. It’s just a PR you submit to the repo. Make sure to give Geoff credit though. I don’t think there’s currently a way to have more than one author on an article.
Geoff.
Geoff.13mo ago
i'm sure he will do that thanks for mentioning 🙂
awcodes
awcodes13mo ago
I’m sure he will too. Just wanted to call it out.
Hegabovic
HegabovicOP13mo ago
sure thing to do 😄 😄 dont worry 😄 i have a simple question , i created the author file and the avatar , where to put the article 😄 😅
awcodes
awcodes13mo ago
content/articles There’s a section in that link that goes over it. You’ll need to convert your gist to markdown, but should be fairly straight forward. Might already be in markdown. Just looking at it on GitHub.
Hegabovic
HegabovicOP13mo ago
yeah i made it in .md formate 😄 done 😄 i'm really excited 😄
awcodes
awcodes13mo ago
I’m excited about our community. You went from being upset about getting help to submitting an article about your experience and helping others who may have similar problems. I LOVE IT. In the span of a few days. It’s really freaking awesome.
Hegabovic
HegabovicOP13mo ago
thanks a lot for providing me this opportiunty ❤️ ❤️
awcodes
awcodes13mo ago
Any time. Good things in, good things out.
Hegabovic
HegabovicOP13mo ago
here is the PR 😄 hope to see it soon on filament 😄 https://github.com/filamentphp/filamentphp.com/pull/219
GitHub
filament integration with Tenancywithlaravel Full Guide Article by...
a step by step guide which will take your application from single user to multi-tenant application
raysaber
raysaber13mo ago
Hello, may I join? I have followed that guide. but still can't make it right 🥲 , the tenant database already detected, but when I try to login in admin panel, it's try to connect to central database. should users table add to central database?
Hegabovic
HegabovicOP13mo ago
i did it multiaple times on new project and pre-existing project and it always work 😄 , and no you dont need a users table in the central domain please re-check steps if not working we can check it together 😄
raysaber
raysaber13mo ago
thank you for confirm, i'll try new setup
Geoff.
Geoff.13mo ago
Be sure to have two different panels one for admin and one for tenant and also don't forget to add set this code in the boot function of the AppServiceProvider
Livewire::setUpdateRoute(function ($handle) {
return Route::post('/livewire/update', $handle)
->middleware([
'web',
InitializeTenancyByDomain::class,
]);
});
Livewire::setUpdateRoute(function ($handle) {
return Route::post('/livewire/update', $handle)
->middleware([
'web',
InitializeTenancyByDomain::class,
]);
});
To make the login work and other stuff but you also have to check if you are in a tenant or in the admin
raysaber
raysaber13mo ago
thank you so much @Geoff. , I'm not realize Livewire had different approach, because on documentation have different config.
Geoff.
Geoff.13mo ago
also something i found here in the discord hehe
Hegabovic
HegabovicOP13mo ago
The PR is not accepted yet 😂
Want results from more Discord servers?
Add your server