HAProxy load balancer in front of Phoenix nodes

Is it a common practice to put a load balancer like Nginx or HAProxy in front of different Phoenix Nodes?
My question is because maybe a single Phoenix web server is capable of handling even more open TCP connections than a single reverse proxy in front of them, because maybe the reverse proxy will go down before the Phoenix web server does. I’m even assuming I have a failover technique for the cluster of reverse proxies.

Also my question is, which is the recommended way to horizontally scale phoenix web servers?

Definitely this is a question from a newbie :slight_smile:

Thanks in advance

From what I’ve heard most people do set up a reverse proxy in front of Phoenix. I haven’t had to run a Phoenix server in production but I’ve used nginx in front of other servers with no issues and would probably do it with Phoenix.

I think it’s generally easier to manage SSL and configuration this way; I don’t think you’ll run into performance issues. That’s my 2 cents anyway.

2 Likes

It really depends on your deployment architecture.You would typically use some sort proxy as a load-balancer to send traffic to more then one application server. That would simplify your deployments, as it is easier to drain nodes.

You would also handle ssl certs on the front-end nodes. Configure all your cypher suites and such.

If you have microservices, you may also push additional functionality into the front-end layer. For example authentication. Your services may then trust headers as they would be injected by the front-end machine and not user directly.

2 Likes

Hi there

I’ve used a plethora of web servers and proxies/loadbalancers over the years. It all depends on your needs. If you’re a single developer like me, you want the best energy conservation to productivity ratio.

If you have only one site on a VPS then yes, run Phoenix directly!

If you have multiple Phoenix apps and multiple sites then you need something to do load balancing and redirect requests from your 80/443 ports to your apps.

Here i’ve worked with many others and I’d recommend HAproxy, which I’m currently using to handle requests to a variety of apps including Phoenix apps.

Haproxy scales as long as you

  • Make sure your VPS/server never writes to SWAP
  • Don’t have anyother app which is high CPU intensive on the server where you’ve got haproxy

However, even now as we’re speaking I’m searching a way to use cowboy (or another erlang/elixir land app) for the reverse proxy stuff. I want simplicity and energy/productivity conservation because each app you add-> complexity. I was able to find GitHub - heroku/vegur: Vegur: HTTP Proxy Library. However it hasn’t been updated in some time and I’m not sure it has the latest HTTP/2 support.

I got GitHub - tallarium/reverse_proxy_plug: 🔛 an Elixir reverse proxy Plug with HTTP/2, chunked transfer and path proxying support working perfectly with just ONE LINE of code. However it doesn’t support websockets out of the box.
And this is a bummer.

Scaling will depend on other things aswell, your database will be the hardest hit so you’ll have to decide which databases you’ll want to use and scale that before you’ll have worries about Phoenix.

Good luck

2 Likes

Oh, thank you @Andrei . Great explanation. I love HAProxy and it can support websockets :slight_smile:

Great explanation

I asked a similar question on this forum not long ago. Having enjoyed the benefits of a Caddy 2 server in front of Phoenix, I would now go as far as saying that it was a no-brainer. Here’s an updated list of the things Caddy 2 helped me achieve (I presume that most would likewise apply to HAProxy):

• adding support for the latest protocols, such as TLS 1.3 or HTTP/3 (experimental)
• serving a maintenance page when the Cowboy / Phoenix web server is down
• adding security and other headers to all requests, or to a broad range of requests
• adding an authentication token header, e.g. to protect a staging server
• redirecting automatically from the domain root to the www subdomain
• dealing with the issue of trailing slashes in URL paths
• hosting static websites on the reverse proxy server itself
• serving multiple domains / subdomains that share a single IP address

4 Likes

You might be interested in a combination of:

Those two libraries are what I use to serve two Phoenix applications:

Without those applications being aware that they’re behind a proxy. And it’s actually all running on nerves via GitHub - nerves-project/nerves_system_vultr: Experimental - join the #nerves channel on elixir-lang slack if interested (although that is experimental)

2 Likes

I’m a little confused by your statement

By looking at the code of master_proxy it seems to only work if everything is in the same app. There is NO (reverse) proxy forwarding going on on tcp or bsd socket.

When you say you have 2 phoenix applications, do you mean an umbrella or in the same app as in same Elixir mix/release? In my mind “2 applications” means 2 separate things:)

Plus those are missing on the fly configuration capabilities which are what makes Elixir/Erlang… amazing. (And it’s darn difficult to get right with haproxy I have to admint)

The only app I found to do this was reverse_proxy_plug however it doesn’t work for websockets. So I had to experiment with other web servers including caddy to see if they can fit into the haproxy need. From what I see, caddy does a LOT of autoconfiguration and it seems allright, however, performance wise I’m not so sure.

I played with nerves before.
Is the nerves project for the VPS allright when it needs NIF’s which are recompiled (ugprades etc)?

Sorry, yes you are correct in your assessment of master_proxy. I read these posts too hastily and misunderstood the intention. The approach I mentioned is something you could do when you want to run multiple phoenix applications on a single VPS from a single BEAM instance, and is in no way a replacement for a general reverse proxy.

I’m not aware of a reverse proxy type library besides Vegur (which you’ve already looked at).