With Meteor, I’d be inclined to have a separate server per subdomain, each running its own app instance, and whose MONGO_URL (and MONGO_OPLOG_URL) environment variable(s) point to that subdomain’s individual database. You can use the same code for each server, but deploy it with different database connection settings. (This approach could become a bit of a nightmare if you have too many partner accounts.)
Trying to do a shared app running on a single server, but which then connects to different databases depending on who logs in sounds like a whole lot of extra complexity in your app.
To handle this on our app we’re simply attaching an organisation identifier to the user account based on email domain. We then attach this to every document created and pass it as a parameter on our sub/pub so that a user only receives documents owned by it’s organisation.
Why not have one repo/app and a separate instance for each? If you use Heroku you can use their Git hooks so every time changes are pushed to master, it can auto deploy to all severs. This way each customer has their own database, meteor settings, and server. Settings that are configured per customer can be setup in env variables.
Its something I’ve been agonising over. Depending on pay-offs/use case to reduce devops there’s always Auth providers with multi-tenant. Good suggestions above, and a useful thread here on Multi-tenant in case you missed it
It really depends from application to application. I am researching about the same thing and from perspective of logic, number of tenants, future changes, planed maintenance and previous experience with product the ideal case would be (in my specific case) to provide third parameter upon login (to select tenant to which user belongs) and then to use database in background in dependence of the tenant selection upon the login.
Can you please explain why this would be a huge complexity in the app? Having in mind that I am quite new in meteor - is this complexity introduced by the fact that its hard to implement something like this in meteor?
What would be necessary to change (and on which level) in order to allow dynamic database connection per tenant in meteor app?
Have one app and one database, with the approach you’re suggesting (of having a third parameter on login) combined with @ajaay’s approach of putting an organization_id on every piece of data. I’ve done this myself with Meteor, and it’s a nice approach if you want to programatically create sub-domains.
Have one codebase and many apps, each with their own database, using @SkinnyGeek1010’s suggestion of Git hooks for easy deploy to all servers. I’ve also done this approach with Meteor, but there’s a bit more manual dev-ops work required per tenant.
What I wouldn’t do is have a unified landing page where the user selects their tenant (presumably from a database with just a users and a tenants collection in it and then try to hit different databases, each with all of the app-specific collections (and probably another users collection), depending on the tenant chosen at landing-page login-time. Too much fiddling around with different database connections and duplicated user information, in my opinion. Don’t do that to yourself.
I’ve personally gone with 1) above, but using mizzao:partitioner instead of manually putting my own organization_id on every record. It works really well and once each new user is correctly assigned the correct ‘group_id’ you can write all of your pub/sub & methods as if each organisation had their own database. This eliminates the risk of forgetting to manually use the group_id in every new pub/sub/method and allowing data to be exposed.
It looks like mizzao:partitioner hasn’t been updated for a while but it works really well for me on Meteor 1.4.2. I’ll be trying 1.5 soon… Working in production here: https://www.virtualinout.com/
I was initially going to use sub-domains as you are planning to do, but in the end that made SSL much more expensive (compared to lets-encrypt which is free and automatic but doesn’t support wildcard SSL). In my case the Admin for each organisation has to add/import their own users, and thanks to mizzao:partitioner all imported users automatically inherit the ‘group_id’ of the admin. In the end I dropped the subdomain.
Another benefit of having everyone in the same database is that as the developer you can see all the data from all the different organisations in your own admin panel (or ‘root panel’ as mine is called). You can then assign to yourself the ‘group_id’ of any of the organisations and use the app as if you were part of that organisation.