Hi everyone,
We’d like to share a module we’re developing at LibreCode: [multitenancy-global-config]( GitHub - LibreCodeCoop/multitenancy-global-config: Multi-tenant global config loader for Nextcloud: resolves $CONFIG per request host from a domain config matrix · GitHub )**, which solves a common problem for people running Nextcloud in a multi-tenant setup.
The problem
A single Nextcloud instance serving multiple domains (e.g. `tenant01.example.coop`, `tenant02.example.coop`) often needs different settings per domain: database, SMTP, data directory, and so on. Nextcloud doesn’t provide a built-in, structured way to load configuration based on the request host.
How it works
Nextcloud already loads and merges every `config/*.config.php` file into the global `$CONFIG`. This module takes advantage of that:
- A tenant matrix lives in `config/multitenancy.database.php` (the filename intentionally doesn’t end in `config.php`, so Nextcloud won’t auto-load it).
- A loader, `config/multitenancy.config.php` (which *is* auto-loaded), reads the request host (`HTTP_HOST`) and passes it to `Manager::getConfigFromHost()`, which matches it against the matrix’s regex keys and returns the matching tenant config — or an empty array if nothing matches.
Matrix keys are full regular expressions (with delimiters), and the first match wins. Values are regular `$CONFIG` arrays, merged over the global config. Example:
$CONFIG = [ '/^domain01\.example\.coop$/' => [ 'dbname' => 'tenant01', 'mail_smtphost' => 'smtp01.example.coop', \], ];
Trust boundary
The `Host` header is fully client-controlled. That’s why the regex keys are anchored (`/^…$/`), preventing one tenant from selecting another tenant’s config. A host that matches no key falls through to the **base** config — so it’s important to configure your reverse proxy to only route known tenant hosts to this instance.
CLI (occ, cron, background jobs)
CLI processes have no `Host` header, so they fall back to `localhost`/base config by default. To run a command as a specific tenant, just set the environment variable:
HTTP_HOST=domain01.example.coop php occ maintenance:mode --on
Installation
The module is location-agnostic — you can clone it (or add it as a git submodule) anywhere the PHP process can read, inside or outside the Nextcloud webroot:
1. Copy `examples/multitenancy.config.php` into your Nextcloud `config/` directory and adjust the `require_once` path to point to where you cloned the repo.
2. Create `config/multitenancy.database.php` with your tenant matrix (see `examples/multitenancy.database.php`).
The matrix filename can be overridden via the `MULTITENANCY_CONFIG_FILE` environment variable.
Licensed under AGPL-3.0-or-later. Feedback, testing, and contributions are very welcome!