Hacker News new | ask | show | jobs
by coderobe 2800 days ago
>And besides: If Sinatra starts a server listening for incoming traffic, why does it still seem common to run a regular webserver like nginx in front of that server?

This is a common technique used for tls-termination and management of 'virtual hosts', among other things.

The mentioned "issues" don't seem to be Sinatra-specific, but rather about the authors shallow understanding of the topic as a whole

3 comments

> This is a common technique used for tls-termination and management of 'virtual hosts', among other things.

Yes, usually you're not hosting only one application in a server, it's very useful to have the abstraction of a layer on top of many apps.

Also, to serve static content.

One of these "other things" is buffering of slow HTTP requests. Application servers are usually not designed to deal with that and are meant to be run behind a proper load balancer/reverse proxy. This is usually very explicitly mentioned in their documentation, for example in https://bogomips.org/unicorn/PHILOSOPHY.html
puma does pretty good at buffering slow HTTP requests though.

I honestly _don't know_ why we usually put apache or nginx in front of our ruby 'web servers'. But I keep doing it anyway, cause 'everyone else' does, and I don't want to take the time to be sure I don't need to, it works.

However, I believe rails deployments to Heroku generally _don't_ put another web server in front. Which, per your point, slow clients is quite exactly why they explained the switch from unicorn to puma as a default web server. https://devcenter.heroku.com/changelog-items/594

It is true that in 2018 web dev has gotten complicated (in a variety of different axes), and if there's a framework/platform that will allow you to not know it is, I don't know what it is! It would probably be one that made a lot more choices for you though (like, say, ruby web server, so you don't need to think about 'oh, unicorn can't handle slow clients but puma can') -- which is the opposite of Sinatra's philosophy -- but then again Rails approach to try to do that has not resulted in something people find easy either. shrug.

I've stopped using Nginx in my Docker containers, and I just run puma directly. It's still behind a load balancer that also handles TLS termination. I also serve all the assets from the Rails server, but they're cached with a CDN, so it only needs to serve each file once.

If you're using Docker with Kubernetes, Convox, Docker Swarm, Rancher, etc., then I don't think you need to run Nginx or Apache. I ran some load tests on my staging environment with and without Nginx, and it didn't make any difference.

This was a really good article that helped me understand request routing a bit better: https://www.speedshop.co/2015/07/29/scaling-ruby-apps-to-100...

If you weren't caching with CDN, would serving those static assets as efficiently as possible be a good reason to keep using (eg) nginx, do you think?

Oh, I guess load balancing (with a multiple-host scale) is another good reason, if you don't have heroku doing it for you, nginx is a convenient way to do it just fine.

I don't know if there's any middle ground where you'd want to use Nginx instead of a CDN. If it's an internal app then it doesn't really matter. But if you have any reason to worry about the performance of serving static assets, then you should always be using a CDN like CloudFront or CloudFlare, etc.

But yeah, Nginx can be a great solution for load balancing and TLS termination.

I always used to do it for static asset serving, where anything standing between the socket and a sendfile() call is a waste of space. I honestly don't know how good Puma is at sending files, but I wouldn't be shocked to learn it was still worthwhile there.
Apache httpd mod_proxy -> a smattering of docker containers