Run Phoenix without using Nginx

How do you run Phoenix without using Nginx? Do you use iptables or authbind?

Edit: Added link below.

Running on Port 80 and Port 443

2 Likes

iptables seems the easiest / most reliable. I tried redir too a while back but this does not really bring any advantages over 2 lines of iptables config.

1 Like

Thanks for sharing. I actually haven’t tried any of these yet. I have always been using Nginx as a proxy for the web apps I built. Port redirection/port binding wasn’t part of my vocabulary until I was researching about Elixir/Phoenix deployment best practices recently. I hope more experienced developers would share their experiences and strategies on this because the Elixir/Phoenix docs and books I read don’t teach anything about this.

1 Like

out of curiosity, why you don’t want to have Nginx running? I tend to still use it by default. This comes in handy when I need to temporarily bring the site down for maintenance / upgrades for example, I just set up some temporary landing page. Or in case app crashes for some reason I get the opportunity to set up custom 500 page.

3 Likes

It’s not that I don’t want to have Nginx running. I saw Jose Valim’s comment on this stackoverflow question and I realized that it would be more straightforward to serve Phoenix directly.

Your points for using Nginx to handle situations when the site is down are important to keep in mind. Thanks.

There is also the issue of static files. Nginx is faster in serving static files. When using Nginx, the Phoenix server will be free to handle only dynamic requests.

Well on one of our Windows servers here at work we have IIS in front of a Phoenix server. I would not recommend that, at all…

1 Like

I second Jose’s suggestion - why do you need Nginx? Start with the simplest and then build up. Phoenix/Erlang is mighty amazing at serving static files too. If that is a bottle neck then by all means use nginx.

I’m using iptables for my blog.

When I deploy new version, I start another docker container with the new image, reroute iptables, and then stop the previous one. Actually it’s a bit more involved than that, but that’s the general idea which allows me simple “downtimeless” updates without needing to use OTP release handling.

This should be easy to do with some simple maintenance plug somewhere at the top of the endpoint. The same thing holds for a custom 500 page.

If supported by OS, static plug will use sendfile syscall, meaning that a file will be sent to the socket from kernel, and its content won’t be loaded into BEAM OS process. It should of course be measured, but I’d expect serving files from Phoenix shouldn’t be “significantly” slower compared to nginx.

Also, dynamic requests should be somewhat faster with Phoenix alone, because there’s one hop less. More importantly, the architecture is simpler, because you need one component less on the server. This is the main reason why I’d advise starting with just Phoenix, and moving to nginx for some specific reasons. You start simple, and reach for additional technology if you really need it.

7 Likes

@sasajuric … Thank you that was informative… I ran some testing using weighttp tool and here are the results:

Root page /:
Phoenix alone: ~ 2100 req / sec
Nginx + Phoenix: ~ 1600 req / sec

Static image:
Phoenix alone: ~ 2400 req / sec
Nginx + Phoenix: ~ 12000 (12 thousand) req / sec

1 Like

what kind of hardware/os/vm were you running these tests?

I wonder if Cowboy does the same network optimizations that Nginx does. Looking at the results from @acrolink I have strong doubts that it does. More info of what they did in Nginx: https://t37.net/nginx-optimization-understanding-sendfile-tcp_nodelay-and-tcp_nopush.html

out of curiosity, why you don’t want to have Nginx running? I tend to still use it by default.

Late to this, but – in the Real World, all my servers, regardless of
what kind of app they’re running, are constantly flooded with attack
“requests” for “admin.php”, “foo.aspx”, etc.

Using nginx as a front end to discard those saves my app cycles in
generating 404s, bandwidth in returning them, and polluting my app
logs with pointless entries.

YMMV.
Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
http://about.me/hassanschroeder
twitter: @hassan
Consulting Availability : Silicon Valley or remote

5 Likes

@hassan … I experience the same, Nginx can block and filter those kinds of unwanted activities at the entry point and it does this task very well…

OpenSUSE Leap 42.1, 4 G.B. Ram, 2 CPU cores on a shared server environment running Intel Xeon CPU E5-2680 v3 @ 2.50GHz

I interpret it as @hassan prefering not to run nginx because of the numerous entries and serving of 404’s etc. But I could be totally misinterpreting this of course :smile:

I interpret it as @hassan prefering not to run nginx because of the numerous entries and serving of 404’s etc. But I could be totally misinterpreting this of course

Yeah, I was saying exactly the opposite - nginx as a front-end filter
keeps the trash out of my logs and prevents wasting bandwidth on
servicing nonsensical “requests” :slight_smile:

Hassan Schroeder ------------------------ hassan.schroeder@gmail.com
http://about.me/hassanschroeder
twitter: @hassan
Consulting Availability : Silicon Valley or remote

2 Likes

Yeah I have to state that I have a lot of ‘dead-paths’ in my nginx configs as well, that really is a great boon.

1 Like

That makes sense. Thanks for clearing it up!

If you really do not want to use Nginx, but your VPS does not support port redirection with iptables (which is the case for many OpenVZ based VPS) you can always use xinetd (https://github.com/xinetd-org/xinetd).

1 Like