1 umbrella app, can I host different apps to different Heroku apps?

I’ve been trying for two days to get an Elixir umbrella app to work on Heroku with a proxy app on a single heroku application to no success. It seems like I’m hammering my head against a wall haha.

I was wondering if I have this umbrella app:

  • App
  • App (elixir)
  • AppWeb (phoenix)
  • AppMarketing (phoenix)

Can I deploy it to two different Heroku apps in such a way that AppWeb runs on one app, and AppMarketing runs on a different heroku app? While both can share the business rule library of App?

This umbrella application is in a single git repository by the way.

Appreciate any helps with this! As my last recourse I’ll just use a single monolith phoenix app with scoped routes, but I would hate to do that if I can avoid it.

Elixir and Erlang/OTP do allow for communication between applications on different nodes but if you’re only just getting started and you’re not experiencing any actual problems with the current setup, using just one Heroku app for your whole umbrella application is probably the best way to go :slight_smile:

What is your reasoning for wanting to use multiple Heroku instances instead?

1 Like

Umbrella applications are code-design concepts - just an easy way to develop related applications together and share code etc.

What you want is to create two different releases:

Release A will run App + AppWeb
Release B will run App + AppMarketing

This will work if the App is a library application, i.e., just a bunch of functions without its own supervision tree. If however it starts its own tree, which for example is the case if it uses Ecto, you would be better placed to run it only once. You will need to add extra configuration to your apps to teach them how to find the other nodes, and deal with Heroku’s daily restarts, firewalls, internal networking and so on.

All that said, as you’ve found out, dealing with complicated releases and distributed Erlang/Elixir adds significant complexity in your Ops. Since you don’t need to change your code dramatically to do this split later on, it’s best to start by running everything on a single node.

5 Likes

Hi,
maybe it’s not what I should do but I won’t answer the question “How can I have 2 heroku apps with one umbrella” but talking about my experience about the first case: one umbrella with a proxy deployed on heroku.

I presume that you know this resource: https://github.com/wojtekmach/acme_bank
Which is a (working) example of an umbrella app deployed to heroku with a proxy.
I followed this example for my own project and it works fine.

But Is encountered 2 problems:

  • it is for phoenix 1.2 and as you know, phoenix 1.3 is out
  • the phoenix-based apps are complete phoenix app as you expect a mix ph(oeni)x.new to build. But if you have ever done a mix ph(oeni)x.new --umbrella, you’ve seen that structure is quite different (and more interesting): it is like this
    project_umbrella
    |_ project
    |_ project_web
    Adding parts to this structure is intuitive, and in fact, the project app will hold the proxy code

Working example is better than words, especially considering my poor english.
Feel free to look at: https://github.com/dominique-vassard/vinculi
where I’ve implement these structure (with phoenix 1.3) which is deployed to heroku via travis.

Hope it helps and don’t hesitate if you have any question.
I’m kind of elixir newbie but be pleased to help :slight_smile:

1 Like

I’ve decided to go this route here: https://stackoverflow.com/questions/7713042/deploying-2-different-heroku-apps-with-same-code-and-git-repository

The problem I had with the proxy approach was SSL issues and websocket connectivity problems.


So in my Procfile if I want to run the mix phx.server command for one of my apps, how do I cd into the right app folder to only run that application? Any tips?

cd apps/your_app && MIX_ENV=prod mix phx.server should do the job

Hi @domvas ,

We’re also interested in deploying an umbrella app with multiple phoenix apps on heroku. We saw your project, but it seems that a few weeks ago you rolled back the idea of a proxy. https://github.com/dominique-vassard/vinculi/pull/10

Could you maybe elaborate on this? Was it just to get websockets to work, or…?

Hi,
Websockets/Channels are the only I don’t use proxy anymore.
Launching phoenix at the apps root don’t allow websocket to work.
I don’t know why, it seems other persons face this problem but I haven’t found any solution.
The problem is that the /socket is not found with proxy.
I confess that I choose the easy path (not solving the error).

But one thing I’ve just thought of and didn’t explore is that maybe the proxy works only on http(s) request and not on ws:// ones, and something has to be done specifically for this.

In fact, I’m not sure wether Channels works with the plug stack which means no redirection to the right app.

This may be relevant to the Plug proxy/channels issue.

1 Like

Conceptually:

Assuming they are different OTP applications and are not dependent on one another this is fully doable with erlang releases and separate bootscripts.

You can create multiple boot scripts for your erlang release. One for starting one of the phoenix apps (and its dependencies) and another to start the other one.

Practically, I don’t know if there are any existing tooling that helps you with this so you might have to drop down to creating these things manually. http://erlang.org/doc/man/script.html

1 Like

Very interesting.
Will check and test as soon as I can!

1 Like

Thanks @domvas

We don’t have such requirements just yet so I think we are good for now. We’ve actually simplified our setup, and right now we only have one phoenix app and one “data/business rules” app.

We’ll see how things go when we need a separate phoenix app.

1 Like

Just curious, how were you able to serve multiple web apps on Heroku? Doesn’t each have to run under its own port? Heroku doesn’t allow access to ports. I think you are limited to 80 and 443. How would that work?

@jeroenhouben where you able to get this to work using multiple ports?

no we went for mono repo, multipe heroku apps.

I’ve been serving multiple apps with a custom endpoint proxying to the other endpoints. The other endpoints had server: false in their configuration. However I recently started using websockets and that’s where this setup fell short. Now I use a nginx proxy in front of the application. So still one application on heroku serving multiple applications with multiple endpoints.

https://hexdocs.pm/phoenix/1.3.0-rc.1/phoenix_behind_proxy.html

2 Likes

@nivanson, can you share some more details on how to achieve this configuration with nginx? I am interested in the Nginx configuration and also what command you use in the Procfile.

This doesn’t answer your question about using Nginx, but another way of doing it is using master_proxy to reverse proxy to different endpoints within one release, which also works at services like Gigalixir, Render (where my app is) and, apparently, Heroku, where there’s only one port is exposed.

Websockets are also apparently supported.

Hi David, thanks for sharing I looked at this one and I will give this one a try. But I think @nivanson has mentioned that a similar setup was not suitable for websockets. The application I am building needs websockets for some features.

Hi @arjun289
I’m running an umbrella app with websockets on Heroku for over a year now, without any trouble

Here is my setup: https://gist.github.com/cblavier/0c2cf3f101d82c32503774f179a66a3f

2 Likes

Thanks @cblavier this looks awesome, I will implement this. I was trying to implement it via the Nginx way on heroku, but I am facing some roadblocks.

1 Like