Optimal architecture for multi-user django application

I was thinking about the right / optimal way to build an application based on multi-level applications in Django.

Some explanation:

  • The application can be used by several tenants (tenant1, tenant2, ...,).

  • All individual tenant data must be protected from access by other tenants (and their users).

  • If desired, tenants can create additional custom fields for application objects.

  • Of course, basic equipment limits the number of tenants on one "system."

1) Separation of each tenant, for example. subdomain and use of tenant-specific databases in the underlying layer

2) Using some tenant identifier in the model to separate tenant data in the database

I think about the deployment processes, the performance of system parts (web server (s), database server, working node (s), ...)

What would be the best setting? Where about pro and con?

What do you think?

+53
django architecture multi-tenant
Aug 25 '11 at 17:01
source share
3 answers

We built the platform using the following architecture. Hope you find some helpful hints.

  • Each tenant receives a subdomain (t1.example.com)
  • Using request rewrite url for a Django application is being rewritten to something like example.com/t1
  • All url definitions are prefixed with something like (r'^(?P<tenant_id>[\w\-]+)
  • A middleware processes and consumes tenant_id and adds it to the request (e.g. request.tenant = 't1')
  • Now you have the current tenant available in each view without specifying the tenant_id argument for each view
  • In some cases, you do not have a request. I solved this problem by binding tenant_id to the current thread (similar to the current language using threading.local )
  • Create decorators (e.g. knowledgeable login_required tenants), resellers, or factories to protect views and choose the right models.
  • As for databases, I used two different scenarios:
    • Configure multiple databases and configure routing according to the current tenant. I used this at first, but after one year I switched to one database. The reasons were as follows:
      • We do not need a high secure data sharing solution
      • Different tenants used almost all of the same models.
      • We had to manage many databases (and did not create a simple update / migration process)
    • Use one database with some simple mapping tables for users and different models. To add additional and specialized model fields, we use model inheritance .

As for the environment, we use the following setting:

From my point of view, this setting has the following pro and con:

Pro:

  • One instance of the application, knowing the current tenant
  • Most parts of the project do not have to worry about specific problems with the tenant.
  • A simple solution for exchanging objects between all tenants (for example, messages)

Contra:

  • One pretty large database
  • Some very similar tables due to model inheritance
  • Not protected at the database level

Of course, the best architecture is highly dependent on your requirements like the number of tenants, the delta of your models, security requirements, etc.

Update . When we looked at our architecture, I suggest not rewriting the URL as indicated in clause 2-3. I believe the best solution is to put tenant_id as the request header and extract (point 4) tenant_id from the request with something like request.META.get('TENANT_ID', None) . This way you get neutral URLs, and it's much easier to use Django built-in functions (like {% url ...%} or reverse() ) or external applications.

+49
Aug 25 2018-11-18T00:
source share

Here are some pointers to related discussions:

+4
Jan 31 '13 at 10:23
source share

I recommend taking a look at https://github.com/bcarneiro/django-tenant-schemas . It will solve your problems a little as mentioned in Reto, except that it uses postgresql schemas.

+1
Feb 05 '13 at 9:45 am
source share



All Articles