Nginx 1.9.11 with Dynamic Modules
mailman.nginx.org
mailman.nginx.org
In NGINX 1.9.11 onwards a new way of loading modules dynamically has been introduced. This means that selected modules can be loaded into NGINX at runtime based on configuration files. They can also be unloaded by editing the configuration files and reloading NGINX.
I'd rather trust the package/security team of my favorite distribution to do this for me.
When you live in the modern world of cattle not pets you optimize for things like this.
That being said our current nginx solution lives in a Docker container on top of Kubernetes so it would be fairly trivial at this stage to build our own nginx and bake it in... but I have to pick my battles.
Although one advantage of requiring compilation is the user is probably more likely to use the latest version.
We'll take a read through the comments here and are looking forward to answering questions and receive feedback. You may also email the NGINX development mailing list (info in blog post).
(I work @ NGINX).
I've just created a separate HN submission pointing to your blog post.
I hope you don't mind.
Keep up the amazing work!
While I'm not on the bandwagon that says all Apache installations would be better on nginx (and I still run Apache on all of our servers, except nginx test machines), I do think this makes the case quite a bit more compelling, particularly for people who package and distribute the web server (OS vendors, control panel maintainers like me, container builders, etc.).
It's worth to note that an nginx fork called Tengine (by Taobao) has a similar feature before.
I just see a single bullet point regarding "Dynamic modules", anywhere I can get more info?
load webserver.nlm
(a reference for the old-timers here)Seems an odd feature for 1.9.11, why not wait for 2.0?
load_module "modules/ngx_http_image_filter_module.so";
load_module "modules/ngx_http_headers_more_filter_module.so";
load_module "modules/ngx_http_set_misc_module.so";
load_module "modules/ngx_http_echo_module.so";
load_module "modules/ngx_http_geoip_module.so";
load_module "modules/ngx_stream_module.so";As it stands, though, the module system would be very helpful for OS packagers, because they don't have to worry about signature mismatch.
This is going to create headaches for anyone wanting to package nginx, either they will have to compile all the modules when building nginx (creating many sub-packages) or there will have to be coordination between package maintainers to do a mass rebuild of all loadable modules every time the nginx package gets bumped. Neither situation is desirable, and I hope they release a stable ABI because until then nobody is going to waste time packaging loadable modules.
Sidenote: creating Debian packages is an intimidating task.
2. Use a standard build/packaging system. autotools, cmake, scons, setuptools/distutils, maven, gem (read: not bundler), cpan, etc. Whatever is considered a "standard" way of building and releasing software in the language you are writing it in is acceptable, using hacked together Makefiles and build scripts is generally a quick way to make packagers hate you and not want to waste time getting your software built.
3. Don't vendor dependencies - if you do then support the use of system-installed libraries in their place. I won't package software that insists on vending dependencies, I'm happy to package an extra library or two but I don't have that option if you don't support it.
4. Please support a standard installation mechanism if at all possible. I can relocate your build artifacts to the buildroot if necessary, but then I have to maintain it as the upstream changes - and distributions may be inconsistent with each other. If you are using a standard build system this should come for practically free unless you've done some nasty hacks, in which case please reconsider the modifications you have made.
Debian packaging is pretty simple but I find the decision to use Makefile's for debian/rules to be a little annoying. rpmspec's are a lot clearer and rpm macro's are a lot easier to intuit since you can easily use rpmspec -e to see what they expand to, versus the blackbox that is the debhelper scripts sometimes.
If you are new to packaging seriously take a look at making RPM's your first stop, rpmdev-newspec has a lot of templates for spec files that make getting started with any project that uses a standard build system super-easy (automake, cmake, python, ruby, perl, etc).
3. I couldn't care less what you won't package. Especially so if it's due to prioritizing your own needs over everyone else's. Take it or leave it.
4. Distributions are already woefully inconsistent anyway. If you're going to package something, the entire burden is on you.
Distributions have had too much influence over upstream projects for way too long. Thank god people are finally starting to reject their diva-like, our-way-or-the-highway attitudes. I have been a package maintainer for both Fedora and Debian, and frankly, for things outside of the core OS/libs/compilers/tools, using deb/rpm packaging is very, very overrated. Likewise for dynamic linking.
Great, and nobody said you had to. If someone likes your application enough and they want to get it packaged they will - personally, however, ease of packaging is something that makes or breaks whether I "like" something - which is why as much as I love Mumble I'm not putting any effort in to revive its package in Fedora, because ICE is a huge pain in the butt to build and I just don't want to waste time on it.
> 3. I couldn't care less what you won't package. Especially so if it's due to prioritizing your own needs over everyone else's. Take it or leave it.
Outside of commercial distributions this is literally how everything works. I package things that are useful to me that I hope would be useful to other people, but I don't know of many package maintainers that spend time on software they personally have no use for.
> Distributions have had too much influence over upstream projects for way too long. Thank god people are finally starting to reject their diva-like, our-way-or-the-highway attitudes.
If you don't want distributions to have so much influence over packaging your software then do it yourself, nothing makes me happier than seeing .spec files or debian/ folders inside a repository of some application I'm looking at - 99% of the work is already done outside of maybe cleaning the scripts and metadata up to meet packaging standards.
> and frankly, for things outside of the core OS/libs/compilers/tools, using deb/rpm packaging is very, very overrated.
I too at one point believed this, but then I remembered how crappy package management on Windows is as a result of this philosophy. They even HAVE a package manager (MSI/Windows Installer) that nobody uses properly! And you know what, good luck hoping all your applications have kept every dependency and every transitive dependency they bundled in up to date - when you get your package included in a distribution that's done for you by the package maintainer that is supporting your package.
> Likewise for dynamic linking.
Strongly disagree. I hope you have fun downloading update bits for every application that statically links against openssl next time some stupid bug like heartbleed comes along. I still think Google made the wrong call with Go, same goes with Mozilla and Rust.
> same goes with Mozilla and Rust.
Dynamic linking in Rust is as easy as passing in a single compiler flag, which is what I expect distro package managers will do when building packages written in Rust.(But I'd really love a way to distribute binary modules anyone could just use, with no additional compilation.)
Of course, serving the output would be harder, but still not impossible.
We'd also need to write a script that looked at your nginx install and figured out what would be the right precompiled module to download.
For example, one Ubuntu machine with Docker can create build environments for every Linux based distro (and version thereof) that exists, and iterate through all of them when it comes time to build. The setup is not trivial, though it is easier than creating a similar environment with VMs or physical machines.
Plus, if there's a custom module you'd really like to have in your nginx you're practically forced into building your own because there's no way to get that module loaded into the distro nginx.
Yes. There's some overhead to dynamic modules. Yes. There's a (minuscule) performance advantage to static linking.
But having the ability to ship modules independently of the web server core is a very important usability feature which, frankly, outweighs the performance overhead for most installs.
If you're really CPU bound on that nginx instance where you need the additional modules and you removing that overhead gives you that little bit extra performance you need, then you always have the option of hard-linking them.
Is that actually true? I would have thought networking latency overshadows any memory latency introduced in a `call foo@PLT` v. `call *(foo@GOT)`.
Are you aware of anyone who has benchmarked this? i.e. not a microbenchmark e.g. inside something like nginx?
If so, it might be worth fixing the dynamic linker: the cost difference is absolutely fixable, as it's a tradeoff for sharing pages with other processes.
I guess it allows us to split the nginx-included modules into separate packages, but it does nothing to aid with packaging extra modules until nginx provides a stable ABI for modules to use.
http://nginx.org/en/docs/http/ngx_http_stub_status_module.ht...
I'm using the nginx mainline PPA and didn't have a problem enabling it.
This module is not built by default, it should be enabled
with the --with-http_stub_status_module configuration
parameter
I had to compile Nginx myself, because that module was absent. As you can read also on various community pages, boards, etc.Nginx is the only server software that I have to compile myself, just to get a basic status feature. It's a way to upsale people to their NginxPlus which offer a lot more status data in the binary.
Configure arguments common for nginx binaries
from pre-built packages for stable version:
...
--with-http_stub_status_module
...(And, in fact, to work at all when compiling against 1.9.11, since the addition of dynamic modules broke us: https://github.com/pagespeed/ngx_pagespeed/issues/1110 )