Infrastructure for a multi-tenancy Phoenix LiveView app

Hi!

I’m new here, happy to be part of the elixir community!

I have a few questions regarding infrastructure for a multi-tenancy Phoenix LiveView app.

But first here some context:

We’re building a ERP for a niche industry of 100+ customers, each customer can have from 5 to 100+ employees. Each customer will have a subdomain (e.g. {tenantName}.erpproject.com) and database (or schema).
It needs to be highly available and scalable, hence the choice of going with Elixir/Phoenix (even though I’m the only tech guy at the moment and I only started to learn Elixir, Phoenix and LiveView a few month ago, but I’m loving it btw).
I’m a full-stack developer, but mostly went frontend (vue, flutter, etc.) in the last few years. Not really an expert at cloud architecture or devops.

  • what is the benefit of running a Phoenix release on a DO (Digital Ocean) app vs running the server with mix on a droplet? I understand the that a release is precompile into a single unit and the benefit of it. But would running the server on a DO droplet would give me more control (in case of issues, debugging, etc.)?
  • I’m currently building the multi tenancy using triplex (it seems is has not been updated for quite a long time but so far so good on local). Running into a lot of issues currently to set it up on DO. But it makes me wonder if it would actually not be better to just assemble multiple releases instead and have a DO app per tenant. I’m having a hard time identifying the pro and cons with those 2 solutions beside the cost of having to pay a DO managed database and an DO app.
  • Actually I went with DO because I had some past experience with it, but given the context of the project, would another cloud solution be more appropriate? I had a look at fly.io and Gigalixir and I had an easier time setting up a dummy phoenix app with auth module on DO.
3 Likes

I finally managed to setup the multi-tenancy with fly.io and at the end it was finally easier than with DO.
So I’m really considering using fly.io for the moment.

Any cons using this cloud service for scalability? I see they don’t really have managed databases but I guess I could use an external service for that later.

1 Like

Not a cons post :slight_smile: I’m currently using them for Metamorphic (currently running a HA setup on the east/west coast of the US). It’s super easy to scale horizontally/vertically with flyctl (perhaps finding the right commands in the docs can take a moment — but they’re there).

I haven’t yet tried to hook up a managed database partner so I can’t provide any insight, but I did notice they have a section in their docs.

Another pro, I’d say, is their customer support and community forum where it’s pretty quick and easy to get answers to questions/troubleshoot a problem.

And I liked way they handled recent security vulnerabilities like Zenbleed CVE-2023-20593.

links
Phoenix files
fly_postgres

1 Like

Sorry to hijack the thread but that’s interesting. Are you just using their non-managed solution?

1 Like

Not sure if you read the docs below already but my advise would be to skip libraries like triplex and just handle it yourself.

https://hexdocs.pm/ecto/multi-tenancy-with-query-prefixes.html

https://hexdocs.pm/ecto/multi-tenancy-with-foreign-keys.html

That said, if you are relatively new to Elixir and multi-tenancy, I would suggest you take a look at the last link, the foreign keys option. This option is the simplest which also means easier to scale.

6 Likes

Thank you for the links! I’ve been using foreign key for most of the projects so far (non elixir).
I feel given the context it won’t be enough :sweat_smile:.

Triplex actually does use the query prefixes, I guess it should not be too hard to replace it with a custom solution.

Yup. I’ve been looking at Neon recently.

2 Likes

If you use foreign keys, and perhaps you are already aware of this, but check out Postgres’ row level security.

1 Like

I love me some Elixir, but I need to call this out: it’s not magical scaling-sauce that will automatically solve your problems.

It’s easier to write available and scalable code on top of the BEAM, but there are still plenty of traps for the unwary that will produce flaky and/or slow code anyways. For instance:

  • using GenServers for code organization (like the docs say NOT to do) and forcing every web request to wait in line at a single process
  • misconfiguring supervision trees so that a part of the application that crashes stays crashed until the server is rebooted

Regarding multitenancy, I’d recommend unpacking your requirements in more detail before picking a solution. Some things to think about:

  • are the schemas for different customers intended to diverge? If they aren’t, how is your company going to deal with BigCo who needs “just a little customization to close the sale”? Picking a solution that doesn’t match this expectation will lead to a rough time in the future.

  • what are the different customers’ service-level expectations? Is your company going to be fine with telling BigCo #2 that the site is down because BigCo #1 sent too many requests? If not, you’ll need to pick a solution that can isolate failures and/or runaway resource consumption.

  • are your customers big enough to expect an on-premises option? You don’t have to have an already-writen solution for this, but different multitenancy approaches will make this more painful than others so it’s worth considering early.

10 Likes

Thank you for this answer. These are really valid concerns to have!

Another thing which hasn’t been said in the thread already - Phoenix is NOT your application. You might be building a Rails or a Django app but in Elixir Phoenix is just the interface to your business logic. You might want to take a look at the book Designing Elixir Systems with OTP: Write Highly Scalable, Self-Healing Software with Layers by James Edward Gray, II and Bruce A. Tate.

3 Likes

Got it! I actually watched Lance Halvorsen - Phoenix Is Not Your Application (ElixirConfEU 2016) :slight_smile: . Thank you for the book recommendation, I just bought the pdf version!

Hi, I read the topic of foreign keys but as soon as I implemented that all Accounts functionality stopped working (login, logout, register…). Any idea how I fix that?

Hi, when asking a question please be more specific than “stopped working”. Show specifically what you did, and specific errors or other concrete issues you are facing.