Multi-tenancy - Schema per Tenant

We want to deploy Indico as multi-tenancy (schema per tenant). My understanding is that we can use schema-translate_map in SQLAlchemy config, instructions posted here

Our goal is to use url sub-domain as tenant name (tenant_name.indico.com).
I realize we also have to solve STORAGE_BACKENDS as well. We will likely use fs:/opt/indico/archive/tenant_name.

Any guideance would be appreciated.

Hi,

I would strongly recommend to simply run separate instances instead of trying to hack multi-tenancy into Indico itself. Either using containers that would run completely separate copies of Indico’s code, or if you want to share the code between all instances, use the INDICO_CONFIG env var to point to separate config files for each instance (ie separate databases, storate backends, temp/cache/log folders, redis dbs, etc.).

This schema map thing from sqlalchemy you linked to seems like a huge mess especially for an application like indico which already uses many different schemas to group related tables together and comes with db migration scripts - you’d have to somehow run them on all your schemas instead, and somehow keep track of where you have which revision (alembic uses the default schema for its version tracking tables)!

PS: I assume indico.com was just an example since it seems to be used by an unrelated company, but just to mention it: Using such a domain name to provide Indico services would most likely be a trademark violation; in case you do intend to use a domain name containing the word “indico”, please reach out to us at indico-team@cern.ch with details.

Thanks for the fast reply. No, we would never use ‘indico’ in a domain name. This was just an example.

Can you expand on how we could use INDICO_CONFIG env var? Where would I insert the var? I assume this is a session var. My goal would be to set this var at run time per session (so I don’t have to start / restart indico) I am able to swith tenants in the indico_conf which does not solve my requirment where tenants can share code.

You would run multiple uwsgi and celery instances (systemd foo@ services may come handy here!) and set the env var in the uwsgi config and celery systemd unit for that instance. Not sure if uwsgi passes on env vars, if it does you could set it for uwsgi via systemd as well.

I am wondering if I could use a tenant variable in indico.conf.
for example: SQLALCHEMY_DATABASE_URI = ‘postgresql:///’+tenant
Where varible tenant = the tenant name that is set at run-time.
If this is possible, where is the best place to set the session tenant varible?

The config file is Python code, so something like this would work in indico.conf:

import os
tenant_name = os.environ['INDICO_TENANT']
SQLALCHEMY_DATABASE_URI = f‘postgresql:///{tenant_name}’

Same for other options of course

I might be wrong, but based on my testing, indico.conf is loaded when app is started. I don’t want to restart the app when adding a tenant.
If this is the case, where in the code can I put
tenant_name = os.environ[‘INDICO_TENANT’]
The tenant name will come from url tenant.corent.com. So I need this to be a session specific varible.

That’s not possible. You need to run separate uWSGI + Celery instances…

Ok, thanks. I will have our engineers go down that path.