SupaSaya

SupaSaya

How to split phoenix umbrella app?

I want to split my app into 2 parts:

server 1: Cache // will feed data to server #2
server 2: Webserver // serve static assets and handle API requests(via #2)

I imagine first step would be splitting app into umbrella project? But I don’t quite understand how to then “distribute” this umbrella project to different nodes(servers). Any examples of last part?

Most Liked

ibgib

ibgib

I’m not 100% on your overall goal, but it sounds like you want to split up the responsibilities of your project into multiple apps. So yes, you would create an umbrella project that would contain multiple apps. Given your description, this is how I would set it up:

  • coolness_umb (project)
    • coolness (app)
    • coolness_cache (app)
    • coolness_web (phoenix app)

The actual “app” logic would go in the coolness app. There are many discussions around about the web server’s distinction from the business logic itself, like here, here, here, and it goes on…(there is even a meta-question here on how important/non-important this is)._ :sweat_smile: I think the structure I’ve given is reasonable for moderate sized projects.

As for the cache, I would point out that for an app just starting it may not even be necessary to implement a cache early on:

Phoenix (without caching) will perform better than Rails (with caching).
We already know this is true on a small app, and we can’t wait to see
how it pans out on a large one. We don’t expect to completely avoid
caching with Phoenix, but it would be nice to avoid having to do it
aggressively and early, as we have had to on our Rails projects to get
reasonable performance and latency. Rails makes it “easy,” but it’s
still time consuming and hard to get right. It also creates friction
that reduces productivity.

I personally implemented a simple cache in ibgib using ets (thus making it local). But I gradually realized that processes on the BEAM can themselves act as an awesome caching mechanism. But I digress… (often).

I recently deployed ibgib to AWS with distillery and docker, and in doing so I only created one release for my entire umbrella application. I ended up with three containers:

  1. Nginx - acts as an https/bare URL redirect only right now.
  2. web - contains my entire umbrella application which includes both the business app (ib_gib) and the web app (web_gib).
  3. postgres - for the data layer.

So I don’t have personal experience with the multiple releases in an umbrella. However, it is mentioned in distillery’s umbrella documentation that you can make multiple release configurations to cherry pick which apps to include in which release. So I believe you will end up in your “release” phase of deployment doing two releases, something like (I’m not 100% on the syntax):

Server 1: mix release --profile=cache:prod
Server 2: mix release --profile=web:prod

EDIT: Per that same distillery documentation page, this will automagically resolve dependencies.

At this point you would have two tars that contain your release and you would deploy each as you would deploy a single release. I personally think Docker is the way to go, with either Kubernetes or Swarm. Also there is Rancher for a higher-level abstraction over the orchestration. Others could speak more to non-Docker approaches. But assuming you would use one of these, (I haven’t personally gotten to clustering yet) a good site I’ve found is on Clustering Elixir nodes on Kubernetes. The “Addendum” section speaks to using a distillery release and vm environment variables for node configuration.

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New

We're in Beta

About us Mission Statement