Hacker News new | ask | show | jobs
by stanleydrew 3928 days ago
I can't help but think this is a bad idea. Jamming more stuff into what is a great tool puts nginx on a slow path to a bloaty death.

Am I incorrect in assuming that you could implement your entire server-side js app now as an nginScript module? Do people think that is a good thing?

Not to mention that putting more interpreters and more end-user code into a system that has access to your service's private key might not be terribly wise.

I'm sure many people will tell me I'm wrong, and I guess I can see some benefit to simplifying configuration and perhaps deployment.

But there's a reason we've mostly moved away from deploying embedded PHP applications inside of mod_php.

4 comments

The usefulness of this is not to turn nginx into an application server. Although there are already frameworks for this using ngx_lua (http://leafo.net/lapis/), I don't find them very interesting except for the technical aspect.

The point is to make nginx's configuration dynamic and prevent bloating applications with stuff that belongs at the (lets call it) devops level.

Now, I also don't think nginScript is such a good idea. But because they seem to be building their own JavaScript VM for it. I believe this is a waste of effort and more of a JavaScript-all-the-things than anything else.

Lua is a very simple language, the VM is small and fast and for the "dynamic configuration" scenario one hardly codes more than a few lines (I've done quite a few things and the total line count is in the low 100's).

It's funny. Any feature you don't want to use is bloat, but as soon as you need it is a necessity. The way I see it, they can either "bloat" nginx by adding scripting capabilities, or they can bloat it by covering all of the use cases that a scripting engine would otherwise enable, big and small.

One simple example that I would love to use this for: generating and adding a UUIDv4 to every request's headers. Doing so would allow us to append the UUID to virtually every log in our entire stack. Right now there is no easy out of box solution for this in nginx. With scripting capabilities it becomes trivial.

However, whether or not Lua was enough and adding JavaScript is overkill, I'm not sure.

I've had the following Lua adding request UUIDs to our logs in production for over a year. Feel free to give it a try:

https://gist.github.com/erikcw/e999e1fb438dbbb91533

I do what you describe with no extra Nginx modules with the following line inside a location block:

  fastcgi_param X-REQUEST-ID $pid-$msec-$request_length-$remote_addr;
Using the more headers module you can also pluck things like Oauth access tokens and append them too
> generating and adding a UUIDv4 to every request's headers

Why you can't do that in Lua?

You can consider it bloat even if you want it, which is why you want to carefully manage the size of what you add.

I wouldn't refer to JavaScript as 'overkill'; it's not more capable than Lua for scripting, it's just bigger.

We've written extensive partial view caching with memcached in lua in nginx, none of us having known lua when we started. It's fast as hell and the learning curve really isn't steep. Most of the tricky stuff involved the nginx api and brain-wrecking recursive and nested calls - not the language.

They're welcome to spend time building their own JS VM, it's their project - and while I don't think this is intended to appeal to the existing userbase, I think it will attract an entire new userbase, which will further nginx as a webserver and aid the goals of those who use it (faster. faster. more speed. faster. fix the bugs.) as they get more use, more paid use, and thereby more developer time.

I have used ngx_lua in the past for some intelligent query rewriting and was very pleased with the experience. It is definitely great having the power of real programming language at hand and not being constrained by yet another configuration file syntax. On the other hand lua just feels very small and the temptation to fit more of the application logic into web server is low (although apparently not for others as lapis shows ;)).

I guess nginScript is mainly an outreach thing. Apparently nginx developers have decided that all those UI developers are just more comfortable writing JS than anything else. What indeed raises some red flags is that it is a subset of the language running on custom VM. So it is in fact a JS dialect which will still require some amount of learning to use it effectively (no free javascript lunch here).

"The point is to make nginx's configuration dynamic and prevent bloating applications with stuff that belongs at the (lets call it) devops level."

No, let's not call it that, because I have no idea what you mean when you say that.

Throttling, request routing, security workarounds, integrating multiple applications under a single nginx reverse proxy, ...

If you do ops or interact with an ops team, I'm sure you can find many more examples.

Agreed, those are all operational concerns and dynamic nginx configuration is great for that. I was objecting to seeing the term "devops" being further abused.
Some nginx configuration files are very project specific, especially when you have projects using some of the modules they offer.
The purpose is to give the power of LUA scripting (via OpenResty, used by companies like Cloudflare) in the hands of more people, since Lua is a small community (even tho, it's great, easy to learn and fast). Thus, adopting JS is the solution for them.

Disclaimer: we built one of the biggest Lua+Nginx project [1]

[1] https://github.com/Mashape/kong

There is already Lua support so this is just adding another language - thus if this is a bad idea, it is a continuation of an existing bad idea, rather that starting a new bad idea. If that makes a difference....
Yeah I've been skeptical of nginx's Lua support in the past. I guess I discounted it because it was a relatively unknown feature and Lua is obviously not nearly as popular as JavaScript. I don't know of any production service written exclusively in Lua, though I'm sure there are some.

So yes while this is just a continuation of a bad idea, it's a rather substantial continuation. I fear that a lot more people will make use of this than make use of nginx's Lua support.

OpenResty is built on Nginx's Lua support and is fairly popular. You're probably using websites that use it without knowing it.
There's also Lapis, a really great and reasonably feature-full web app framework for OpenResty: http://leafo.net/lapis/. I wrote a website in it recently and was pleasantly surprised at how cool it is. It reminds me a lot of Rails, but everything works faster, especially on LuaJIT, and I actually like MoonScript (the compile-to-Lua language I'm using) for its expresiveness and aesthetics. Definitely recommend checking it out.
We use the lua support in openresty to build our authentication layer for admin tools outside of those admin tools. Very easy to integrate it with a third party authentication platform and just provide auth for free to our app developers.
I have read that cloudflare uses nginx lua a ton. Apparently so does taobao (via tengine?).
AFIAK, CloudFlare is entirely just Nginx+Lua scripts.
That is not fully true.

It became a lot more true during 2013, but CloudFlare had already been operating for a few years then. A lot of fairly simple code was retired to the profit of Lua code, which is way easier to maintain.

There are still important modules written in C and compiled with Nginx. There are also proprietary extensions of the ngx_lua api to manipulate internal some internal aspects of Nginx within the scripts.

source: I wrote a good chunk of both iterations.

> Am I incorrect in assuming that you could implement your entire server-side js app now as an nginScript module? Do people think that is a good thing?

This is kind-of already possible with OpenResty: https://openresty.org/

You can also use Lua, a programming language more than capable of producing efficient web application backends, directly in Nginx config files: https://www.nginx.com/resources/wiki/modules/lua/

So...in a way, this has really been possible for a long time. I'm not disagreeing with you, because personally I'd much rather build my web app in a language and toolchain that's easier to work with, but I find it interesting to read about.