top | item 37453854

Nginx Unit – Universal web app server

679 points| promiseofbeans | 2 years ago |github.com

188 comments

order
[+] jchook|2 years ago|reply
Nginx Unit + PHP seems to handedly out-perform Nginx + php-fpm[1][2][3].

Also, Docker environments running PHP via Nginx Unit will no longer need separate containers for http + fpm, as it works similar to Apache's mod_php.

1. https://habr.com/en/articles/646397/

2. https://medium.com/@le_moment_it/nginx-unit-discover-and-ben...

3. https://github.com/nginx/unit/issues/6#issuecomment-38407362...

[+] ComputerGuru|2 years ago|reply
Those benchmark outcomes are ridiculously in nginx-unit’s favor over php-fpm, way more than I would have believed was possible. What is php-fpm doing architecturally that is so different to warrant such poor relative performance?
[+] conradfr|2 years ago|reply
You don't need separate containers to run nginx and php-fpm.
[+] tiffanyh|2 years ago|reply
Two questions:

1. Does Unit + PHP doing the typical “initialize & teardown” that PHP is know for?

Or is Unit persisting the initialization/setup, hence why it’s achieving the way faster results?

2. How is Unit/PHP architecturally different than NGX-PHP (an event loop)?

https://github.com/rryqszq4/ngx-php

[+] KronisLV|2 years ago|reply
Hey, this is pretty cool to see!

Here's a page with the features: https://unit.nginx.org/keyfeatures/

The languages supported, if anyone is curious:

  Binary-compiled languages in general: using the embedded libunit library.
  Go: by overriding the http module.
  JavaScript (Node.js): by automatically overloading the http and websocket modules.
  Java: by using the Servlet Specification 3.1 and WebSocket APIs.
  Perl: by using PSGI.
  PHP: by using a custom SAPI module.
  Python: by using WSGI or ASGI with WebSocket support.
  Ruby: by using the Rack API.
  WebAssembly: by using Wasmtime.
I'm currently using Apache as a reverse proxy for most apps and sometimes PHP-FPM when I need to run software with PHP, which works well for my personal needs (mod_md and mod_auth_openidc are pretty cool), but it's cool to see something similarly interesting to OpenResty coming along as well, too!
[+] gibmeat|2 years ago|reply
Why the obsession (it seems to be the prominent point in the readme) with configuration via API? How often do you need to add php support on the fly? I want to configure my app server via files so it just starts up in the state that I expect. What am I missing?
[+] Ayesh|2 years ago|reply
Probably the most common use case is SaaS providers that support custom domain name for whatever the software it is. For example, a site uptime monitoring service might offer a feature to host a status page on a custom (sub)domain of the customer. The SaaS now needs to programatically create virtual hosts on demand, issue HTTPS certificates, run routine updates, etc.

An API and a web server with small segmented updates make this so much easier. Compare this to Apache, that has to wait to properly end existing connections before reloading, has a config file parsing overhead, and probably does not scale that well with several virtual hosts anyway. There are hardware/File System level limitations as well.

[+] fragmede|2 years ago|reply
> How often do you need to add php support on the fly?

Restarting the binary means you'll lose requests while it's restarting, so adding php (or whatever) support on the fly is what you need when running a system where losing those requests is material. Which it won't be for most people, but for, eg, Google (who don't use Nginx), losing those requests is a problem.

[+] sneak|2 years ago|reply
This allows you to start up generic machines with no configuration and customize them after boot from a remote host.

It's not so much "on the fly", as it is moving the long-term config storage to a different system.

[+] didip|2 years ago|reply
For webapp, maybe not very valuable.

But for API gateway or any kind of sidecars? Very valuable.

[+] fideloper|2 years ago|reply
I was just playing with this the other day.

Trying to find context on what it was, I saw it’s been on HN a few times (mostly to the sound of people asking the same question).

Since I mostly do php/laravel, I was pleasantly surprised that it let me remove php-fpm from my stack - extremely nice when putting PHP apps in a container.

I personally have come to dislike PHP-FPM’s max_children and similar settings, whose low defaults come as an annoying surprise when you suddenly get gateway errors before your server is even overloaded. (and having to add nginx AND php-fpm “layers” into a container to run PHP apps is all sorts of annoying).

Unit doesn’t have as many features as Nginx so I suspect it’s best used when there’s another fully-featured http layer in front of Unit (to more easily handle TLS, protecting dot files, gzip, cache headers, and the like).

Overall i’m excited to use it when making images for php apps.

[+] Dachande663|2 years ago|reply
Tested this with a moderately complex PHP Laravel app and got a 40% speed improvement. Very useful to be able to run multiple apps each using different lang runtimes/versions without needing separate docker containers.
[+] usrusr|2 years ago|reply
So much JSON... is that the real thing, as in comments are the gateway to hell, or is it actually some practical JSON superset like JSON5?

I almost see myself jury-rigging some bespoke filesystem on-ramp to that REST configuration interface. Likely with at least half a dozen scary security compromises.

Then on the other hand I guess they've never been afraid of getting called opinionated and that's certainly much better than trying to be everything, for everyone, at the same time.

[+] gjvc|2 years ago|reply
JSON without comments is hell, forcing one to 1) convert JSON configuration to YAML. 2) add comments to YAML and admire it. 3) convert YAML to JSON for sending to the server.
[+] otterley|2 years ago|reply
I like to think of JSON as a low-level configuration language that most people should generate from a higher-level language such as Python or JSONnet — sort of like assembly is to C. JSON has lots of things to like about it, but I don’t recommend generating it manually for most people for files larger than a few lines.
[+] jiggawatts|2 years ago|reply
This seems a lot more like how IIS works, unless I'm missing something?

As an aside: it's always curious to see how the programming world has splintered into cliques that no longer hang out together.

NGINX Unit is a "Universal" web server without support for C++, Rust, or ASP.NET!

But PERL is supported, like the 1990s Linux cgi-bin world never went away.

[+] coldtea|2 years ago|reply
In Linux where this is primarily expected to be used ASP.NET is extremely rare, as is C++ for web stuff, and Rust has a vanishingly small web presence still. Lots of people use Perl still though, if not for anything else, for legacy stuff.

So might as well ask why it doesn't support Delphi.

[+] layer8|2 years ago|reply
They should make a page explaining how this differs from Nginx and why it needs to be its own separate thing. I couldn’t find such a page.
[+] donatj|2 years ago|reply
I remember when they announced this a couple years ago I had no idea why I would use it over standard nginx. That seems to still be the case.

It’s JSON controlled via Curl? And has a bunch of langue’s built in for some reason? The question becomes why?

[+] l5870uoo9y|2 years ago|reply
Thought for a second that it included automatic TLS certificates but that is still done manually with Certbot, which also isn’t that difficult.
[+] ComputerGuru|2 years ago|reply
Can you feasibly run this behind nginx (either over http in a regular reverse proxy setup or with sort of more clever shared memory forwarding situation?) so you could, eg use nginx-unit instead of php-fpm but keep everything (ssl termination, rate limiting, etc) centralized behind your core nginx load balancer?

Edit: yes, it’s as straightforward as it sounds: https://unit.nginx.org/howto/integration/

[+] ExoticPearTree|2 years ago|reply
This seems to be a “universal” app server, like gunicorn is for running Pyhthon stuff, php-fpm for PHP and so on.

It was first launched as closed source and the marketing gibberish f5 came up with made it sound like make believe.

[+] pbreit|2 years ago|reply
Can someone explain what this is to a novice web app developer?
[+] nirse|2 years ago|reply
This is a webserver that can run various web applications for you. In a typical setup you'd run a web/http server (nginx or Apache etc) to handle the 'slow' connections to the client and a separate app server (say, an express application, or Django or Rails etc) that is completely separate from the webserver. The web server acts as a reverse proxy, sending the request on to the app server. The response from the app server is then passed to the webserver, which sends it back tot he client. So a request would this path: client -> web server -> app server -> web server -> client.

This is done because web servers are optimised to handle (many) requests from clients (including things like TLS termination, optimised handling of static files, orchestrate to which backend service to send a request and much more), while application servers are optimised to run the application code.

In this model, the web and app servers run separately, for example in separate containers and they have to talk to each other so you have to somehow connect them (often this is done through a network socket).

So what Nginx Unit does is combining the two: it can do the standard web server stuff (not everything a normal nginx can do, but often that's not needed anyway), but also run your application for you, which could, depending on your setup, make your life a bit easier, as now you don't have to tie the two together.

[+] spoiler|2 years ago|reply
I only glanced at the docs, but way they expect apps to integrate with it seems a bit convoluted to me? It's not really a reverse proxy at this

What would be wrong with just using HTTP/2, maybe with a few custom headers sprinkled in for custom features?

[+] tomjen3|2 years ago|reply
This is an interesting idea, but I feel like it is a big oversight not to have build in support for automatically getting certificates.

Instead the docs have you do something manual with certbot (a complete nono if you believe in automatic SSL and are using docker images that don't persist data, as Docker is meant to be used).

The only reason I have SSL on my domain in the first place is that my host offers a simple setup that runs automatically.

[+] lagniappe|2 years ago|reply
I built something like this, but with much simpler syntax and automatic https simply bc I'm not smart enough to reliably set up server blocks and letsencrypt every time I route a new app.

AppServe takes care of all that, and even if I did know the syntax by heart to do it in nginx, this is still faster.

https://github.com/donuts-are-good/appserve

[+] gertrunde|2 years ago|reply
Nginx Unit helped me out of a hole recently - needing to deal with a legacy Python 2.7 web application, while trying to keep it as 'supported' as possible (ignoring the whole python 2.7 thing for the moment!).

Nginx Unit, with their python 2 module, on Debian 11 ended up working petty well.