Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

poorcoder's avatar

[Tip] Single App - Multi Dbs and Domains

Hi All,

I am developing a application and... I want to share my solution with you...

Run this in your console

php artisan make:provider MultiAppServiceProvider 

Open your new service provider and replace your boot method on it...

    /**
     * Bootstrap the application services.
     *
     * @throws DomainNotFoundException
     */
    public function boot()
    {
        if ( ! \App::runningInConsole()) {
            $domain = \Request::server('HTTP_HOST');
            $file = str_slug(str_replace('.', '_', $domain), '_') . '.php';

            // if config file not found throw exception and event
            if ( ! file_exists(config_path('sites/') . $file)) {
                $msg = trans('system.domainNotFound');
                //                event(new DomainNotFound); // you can announce an event... 
                throw new DomainNotFoundException($msg);
            }

            // get settings by domain
            $settings = require config_path('sites/') . $file;

            // set all settings by request domain
            foreach (array_keys((array)$settings) as $key) {
                $replace = array_replace_recursive(config($key), $settings[$key]);
                config([$key => $replace]);
            }
        }
    }

Add service provider to app/config/app.php

App\Providers\MultiAppServiceProvider::class,

Create a directory in app/config/sites ...

return [
    // site settings
    'app'      => [
        'site_name'    => 'Site Name',
        'url'          => 'http://example.dev',
        'school_count' => 2,
    ],
    // db settings
    'database' => [
        'default'     => 'mysql',
        'connections' => [
            'mysql' => [
                'driver'   => 'mysql',
                'host'     => 'localhost',
                'database' => 'example_dev',
                'username' => 'root',
                'password' => 'pass',

            ]
        ],
    ],
];

You can add any key, values as you wish...

I hope you like it... Its works for me...

Any comments are appreciated...

Thanks

0 likes
11 replies
Aleh's avatar

Thanks! Such solution too is necessary to me. I will observe.

1 like
kaylakaze's avatar

This was a really good tip This has worked great for me, with fairly limited modification to my current code. Thanks.

1 like
kikvors's avatar

Just what I was looking for, thanks! Note that the artisan command above contains a colon too much. This is correct:

php artisan make:provider MultiAppServiceProvider 

The boot() method above requires there to be default configuration keys. Here's an altered version that takes the site choice from your .env file (key APP_SITE) instead of from the current domainname, and doesn't require default keys to exist:

/**
     * Bootstrap the application services.
     *
     * @throws DomainNotFoundException
     */
    public function boot()
    {
        if (!\App::runningInConsole()) {
            $file = env("APP_SITE").".php"; //define site/namespace in your .env file

            // if config file not found throw exception and event
            if (!file_exists(config_path('sites/') . $file)) {
                $msg = trans('system.domainNotFound');
                //                event(new DomainNotFound); // you can announce an event...
                throw new DomainNotFoundException($msg);
            }

            // get settings by site
            $settings = require config_path('sites/') . $file;

            // set all settings by site
            foreach ($settings as $key => $value) {
                if (config($key) == null)
                    config([$key => $value]);
                else {
                    $replace = array_replace_recursive(config($key), $settings[$key]);
                    config([$key => $replace]);
                }
            }
        }
    }

Thanks so much for this Tip!

2 likes
poorcoder's avatar

Thanks for the correction @kikvors But I was trying to solve this problem.

My project was a SAAS project. I was trying to be able to use my customers domain names... Customer one : panel.car-dealer.com Customer two : dashboard.book-saler.com

this was the problem I was trying to solve, every new customer just needs to add an A record their dns settings...

Thanks...

codivist's avatar

@poorcoder I like this solution. I'm working on something that will need a similar check to see what domain it's in.

I'm wondering though as I write unit tests and have queue jobs to and from an API. How well does this solution work on the CLI?

So if I write a unit test, I can test it with the default site, but then just for fun I want to test it in panel.car-dealer.com and dashboard.book-saler.com

1 like
poorcoder's avatar

@codivist In my project was using queue jobs as well. We have one app codebase, so you should figure out which owner app is the owner of that job. I solved that with, every job needs a site key which site owner of this job. I send the key for every job when the events is happening.

I hope I understand you correctly.

2 likes
codivist's avatar

@poorcoder Yes! I currently have one codebase and each customer or domain has their own key already for API access I could base it off that or do something similar.

Thanks so much for this, this has helped a lot!

1 like
tprod's avatar

Hi,

Thanks for your solution. I'm wondering how you organize models and controllers . For each app or website it can be different. What is your folder structure do you duplicate app directory ?

Thanks again for your answer

matiazar's avatar

Hi @poorcoder Great solution.. but what about when running in console mode... for example. You need to add a table to the database.. so you must run php artisan migrate on every site/domain... becuase they have different databases. How do you do that? Thanks !

poorcoder's avatar

Hi @matiazar for centralized things like events console mode codes... I say the system "do this with this" I mean when I trigger and event I have to say do this for a.domain.com with this data.

Hi @tprod I am not doing that. On my project all my code base is single no changes needed for any domain... If you have to do that kind of modifications you have to consider not use this kind of solution this will give you big pain when code base grows...

advkumar's avatar

Hi, I am trying to implement this. Can you please clarify the below points?

  1. Create a directory in app/config/sites ... -> What should be the name of the file?

return [ // site settings 'app'

  1. I have a default .env file and added APP_SITE= "domain . test"

How can I add 5 more domains? Should I create "domain . test . env" or in the same default .env file 5 times APP_SITE... ? I am confused about this.

  1. Instead of creating the config / sites / domain1 . php file - can I fetch these values from the DB and use it?

I think this is a great solution to what I am building. But struck with the next steps. Pls. help me with this.

Thanks Kumar

Please or to participate in this conversation.