I install a fresh copy of Laravel in each virtual site dir. For the reasons you state. The configuration is coded into the install. There is no Laravel Shared Library, Instance what ever you want to call it. And 'runtime library'. But thats where composer comes in. In theory it brings in all the correct versions you need. But coming from a Java deployment world all of this duplication of code is a concern.
setup a multisite environnement with laravel 5
hi
i would like to create a multisite app using laravel. i have many virtualhosts on my server and i would like that for each ServerName it displays a different frontend : each "site" would have its own views, its own css, js and its own database (as well as some custom config entries) - sharing the same app.
the cleanest solution i have in mind is that laravel should use an individual .env file for each site. i guess that's something dotenv allows, but i can't see how to get this behaviour without changing the laravel core for it gets :
protected $environmentFile = '.env';
(Application class) and
Dotenv::load($app['path.base'], $app->environmentFile());
(DetectEnvironment class) hardcoded in the vendor path.
What would be the best solution ?
Don't try to achieve it the way you present it. Consider each website as a separated project and deploy a fresh copy of laravel. Environment variables are designed to basically add or remove stuff in production/development/test contexts of your project. If you find yourself implementing re-usable behaviours, extract a package and include it into each project. Much cleaner.
Its quite possible to do this without hacking core files.
I've got an app that runs over 500 domains and sub-domains from 1 install - I'd hate to have to upgrade that many codebases - ughhh!
Format is like sub1.maindomain.tld, sub2.maindomain.tld etc, or otherdomain.tld, otherdomain2.tld etc
Server is setup with maindomain.tld and then each sub domain or top level domain runs as an alias to main server
It currently runs on 4.2 but I'm upgrading it to L5 by using middleware. This runs early to check the requested domain is valid, and set route and config values accordingly.
In this particular case they're quite similar sites and pretty simple, so I dont need to change views, just just a bit css, some js vars and media dirs.
But I expect it would be easy enough to switch views by using view namespaces and dirs in resources/views. Or you could explicity set view file:
php return view()->file($pathToFile, $data);
I also dont need separate db's - in my case separate tables are enough, but its possible to switch the db - your .env file just holds info for main site and main_db - which then holds basic data for each site.
if you run a search for laravel multi tenant or multi site you'll find some quite detailed explanations.
hth
regards
l.
edit: I'm not at my dev machine but iirc there might have been some issues with routing wildcard domains and sub domains. I got round them but I forget how just now.
actually i have searched "laravel 5 multisite" and such before asking, and it didn't show much valuable information
except for this : http://stackoverflow.com/questions/28044322/how-to-have-environment-specific-env-files-for-dotenv-in-laravel-5?answertab=votes#tab-top
So i think i might be able to build my own configuration system using the ConfigServiceProvider . The problem i'm in so far is that whatever i write in the ConfigServiceProvider's register function, it doesn't change anything to my script. Even total syntax errors don't show up. It seems the file is not considered at all, though my config/app.php providers array contains 'App\Providers\ConfigServiceProvider'.
Is there anyway to get the ConfigServiceProvider on i don't get ?
its most likely cached, try running:
php artisan clear-compiled
Hey @kro , I've been trying to do something similar to this but haven´t decided what´s the best solution yet... (https://laracasts.com/discuss/channels/laravel/multisite-cms-one-backend-same-server-folders-assets-general-structure-concerns)...
Have you?
I am currently developing a project that requires these same features, but in my case it is a shared data-set with different brands offering different levels of access to the same resources and controllers, but with different views. In order to achieve this in Laravel 5.1, I have created 2 ServiceProviders and use of the view config file, but it does not seem very elegant to me and I will be trying to implement the same concept by using Route Sub-Domains instead, but this is here for your consumption and works exactly as intended and it can easily be converted to work on a Model instead of config values.
config/view.php - this array replaces the default path array
'templates' => [
'site' => [
realpath(base_path('resources/templates/site')),
],
'site1' => [
realpath(base_path('resources/templates/site1')),
],
],
ConfigServiceProvider.php - retrieves the domain name and matches it to a 'template' name. Can be changed to use a Model instead of a switch.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Request;
class ConfigServiceProvider extends ServiceProvider {
public function register() {
switch (Request::server("HTTP_X_FORWARDED_SERVER")) {
case 'www.site1.com':
$template = 'site1';
break;
default:
$template = 'site';
break;
}
$config = app('config');
$config->set('template', $template);
}
}
TemplateServiceProvider - Overrides the ViewServiceProvider::registerViewFinder method in order to rewrite the path of where the views are found
namespace App\Providers;
use \Illuminate\Support\ServiceProvider;
class TemplateServiceProvider extends \Illuminate\View\ViewServiceProvider {
public function registerViewFinder() {
$this->app->bind('view.finder', function ($app) {
// Set our view to the path defined in ConfigServiceProvider
$template = $app['config']['template'];
$paths = $app['config']['view.templates'][$template];
return new \Illuminate\View\FileViewFinder($app['files'], $paths);
});
}
}
Use laravel forge to create subdomains. I do it -- just makes separate folders basically, and you have to set up your DNS properly, but it works rather well.
The only part that wasn't spelled out for me was to allow wildcard subdomains in the DNS, thats the trick.
- Create ConfigServiceProvider in app\Providers folder and set code:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Request;
class ConfigServiceProvider extends ServiceProvider {
public function register() {
$template = $_SERVER["SERVER_NAME"];
$config = app('config');
$config->set('template', $template);
}
}
- Create TemplateServiceProvider in app\Providers folder and set code:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\FileViewFinder;
use Illuminate\View\ViewServiceProvider;
class TemplateServiceProvider extends ViewServiceProvider {
public function registerViewFinder() {
$this->app->bind('view.finder', function ($app) {
$template = $app['config']['template'];
if(file_Exists(realpath(base_path('themes/'.$template.'/views')))){
$paths = [realpath(base_path('themes/'.$template.'/views'))];
}else{
$paths = $app['config']['view.paths'];
}
return new FileViewFinder($app['files'], $paths);
});
}
}
- Set providers in config/app.php :
App\Providers\ConfigServiceProvider::class,
App\Providers\TemplateServiceProvider::class,
- Create your template forders > themes/{your_domain_name}/views
Please or to participate in this conversation.