I've developed a Web application with Laravel and everything is ok.
This should be a multi-tenant application, so I would like to share the same code but to use a different database for each tenant (I decided for this architecture as according to me it is too complex to share database schema or records among tenants).
Every tenant is accessing the application with its own third level domain (tenant1.xxxx.com, tenant2.xxxx.com, etc)
I would like then to create n. databases (tenant1, tenant2, etc) and to create n. database config file in Laravel (database.tenant1.php, database.tenant2.php, etc)
The problem now is that I cannot find an elegant way to alter the database config file loading system in Laravel.
I should select the config file, based on the host name used by the customer.
Any help would be appreciated.
Thank you,
Michele
in your config folder, there is a 'database.php' file. in that file you can see an array called 'connection' .
'connection' array manages different configuration for multiple database connections.
you can define your configuration for each of tenants in 'connection' array and based on the scenario you are in it, you can choose the appropriate connection to handle your query with a syntax like this:
DB::connection('tenant1')->select('where...');
or
DB::connection('tenant2')->select('where...');
Related
I have a system with many clients, but for each client we have one database "all database and code are the same", but I can set just one database in .env file, how can I set for each client the correct database.
So, on this case I need to create for each client one folder with the same files in each folder, also i did this on my public/index.php
https://onlinephp.io/c/b61dc
but this one I set differents .env for each client with their own databases, so for each client I'll have one .env
There is the best way to do this?
I know that could I use one database for all clients differentiating by customer_id in each table, but on this for now i'll need to change a lot on the system, i'll do this in a v2
Symfony v5.4
I got a legacy code in symphony, but the systems works like this for each client has a system and one database, but the both are same for all of them, so i have "twenty" same systems "folders" for each client and each client has a database.
So, I'm trying to change this to one folder for all clients, but I've been having a problem with the databases, because the file .env we can set only one database for .env file, so, in this case i think to create a folder inside the system "envs" and i created for each client one .env with their names
Example: .envtest, .envgoogle, .envfacebook and etc...
And i use this function on public/index.php to set the corret .env
(new Dotenv())->load(DIR.'/../envs/.env'.explode(".", $_SERVER['HTTP_HOST'])[0]);
and when client trying to access the system i get from the $_SERVER the URL how i can concat and get the corret .env
but i think that i'm doing too wrong, there is other way to do this?
I can understand your problem. You can ask the creaters of symfony and they can help you. Just write your question in thier website here (choose any course and then put your question):
https://symfonycasts.com/
In my case, I have so many databases for my clients but in diffrent servers (LDAP and Soap) so it was easy for me. but in your case it is better to ask Symfony creater themselves.
Important note: This is not about setting up magento2 on one database with multiple websites or store views.
We've setup n domains on nginx, all points to same directory -> /var/www/html/magento2
We need magento2 to run for n different domains with n different databases on same code directory that nginx points so we will be able to release new code only one directory and all websites will be up to date. Of course each domain must be pointed to their own mysql server.
As default, magento2 stores setup based data on env.php for only 1 website setup. There are 2 possible solutions but i don't know how to implement it.
Converting env.php to store multiple data on array for each domains and based on request choosing the correct one from array.
Duplicating env.php n times to domain1.com_env.php, domain2.com_env.php and choosing the matching file based on request.
Any ideas?
So I am developing an application that has two kinds of deployments. One is they host everything and there is one application / one database and no issues. The second (the one this question will center around) will have one application but different database connections per client.
Access to each domain will be white-listed so we don't have to worry about one client popping another clients domain in and their is other authentication on top of that.
What I need is two-fold:
a way to determine the client that is accessing the application (request headers? domain driven?)
grab the configurations for said client so they only access their databases information (use a certain .env file based on client?).
One idea I have thought of is using apache to set env variables based on the domain requested. However, I would prefer to keep this handling inside of laravel. Any ideas?
We do this very thing. As you noted, you need some authority that can map domains to clients, and then a away to fetch the client-specific settings.
Here is how we set it up:
We have different Apache vhost per client, with all the domains/aliases the client has setup. In the vhost file, Apache gives us one single env variable CLIENT_ID. That way we know who the client is, no matter which domain alias is being used at any one time.
We have a Laravel service provider then that looks at env('CLIENT_ID') and sets up a number of config options. One of the things that gets set is a client-specific path, where we store a number of client-specific resources and files. So we're doing something like this:
Config::set("paths.client", "/var/www/clients/" . env("CLIENT_ID"));
Now that we have the client-specific paths setup, we can use Dotenv to go load a client-specific .env file for this client. Note we still have a root .env file in our app directory (Laravel expects it) which sets up common config. The client-specific .env file sets up client-specific stuff like SMTP settings, and of course database connection settings.
Dotenv::load(Config::get("paths.client"));
Now that the client-specific .env is loaded, we can easily write to the database.connections config array. And from there on out, eloquent and everything else just work.
Config::set('database.connections.mysql', [
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
]);
You wouldn't have to do it this way of course. We chose Apache vhosts as our authority for mapping domains to clients, but you could have a master database or just a config file. Then in your service provider, you just need to ask the master db (or the config file) what client needs to be setup.
From there your client settings could even be in the master database or config file, if you didn't want to store separate .env files. Whole lot of ways you can skin this cat.
Ultimately, however you get there, you once you set the database config connection array, you're good to go.
Update:
For anyone reading this in the future, there is another very simple way to load alternate .env files as mentioned in the comments below:
If you set APP_ENV somehow before you get to Laravel (SetEnv in virtualhost etc) it will by default look for .env.APP_ENV (Ex: .env.demo) file. I am using SetEnv to set APP_ENV and then creating .env files for each client.
For our purposes, we didn't want client-specific .env files sitting in the root of our app. But it could work quite well for other situations.
I need to load database and entity configuration in Symfony2 from tables in the database in runtime.
By default, Symfony database config is stored in config.yml. Table names for the entity are defined in #ORM annotations.
But some of my entities can be stored dynamically in any database with any table name and in advance, it is not defined (except table schema), so I can't store database configuration in config.
I want to set the default database config in config.yml. This database will store three tables:
Contains connections to databases (database_connection_id, host, port, user, password, dbname)
Contains relation (entity_name, table_name)
Contains relation (table_name, database_connection_id)
I need to load this configuration dynamically in web request before making requests to entities using EntityManager or EntityRepository. In other words, I want to process this configuration, set table_name and connection for each entity, before processing web requests in Controller. And then work with entities transparent as usually.
As I understand I need to implement something like Symfony ConfigLoader, but there is no database connection while processing configuration. The table name for the entity can be set using Class Metadata, but I am not sure it is the right decision.
A possible way is to generate symfony config.yml for connections and src/*Bundle/Resources/config/doctrine/*.orm.yml for table names (instead #ORM annotations) from database each web request (or once when database config is changed in default database), clear symfony database cache and then load kernel of Symfony. But this way looks ugly.
Furthermore, background tasks can want to work with other tables for an entity than web requests. Each entity can have more than one table, the background task can generate a new table, web requests at this time uses the previous version of the table.
Can this implement using standard symfony flexible components?
I do not think that this is a viable idea. It would come at a great performance cost since symfony caches config files for production and you want to create your configuration at runtime each request.
If you want to do something similar, create a console command that creates your mappings and config files and let symfony clear and recreate its cache with php app/console clear:cache --env=prod or something similar.