Roll-your-own pub sub with NGINX and Nchan on Centos 8!

Categories: FOSS

Publish and subscribe (pub/sub) is a powerful pattern that every developer should know.

And while cloud hosting is awesome, sometimes it’s nice to take a little finer-grained control over the software that’s hosting your application. While working on moggers.gg, the time finally came to add notifications to the stack.

Since the back-end is nginx fronting Flask, I wanted to use nginx to handle the pub/sub workload as well. After looking around at the various options, I finally decided to use the Nchan NGINX extension. The performance numbers looked great, and as FOSS the price was right 🙂

The only catch: there isn’t an out-of-the-box package for Centos 8. So I need to build a custom nginx binary with Nchan included. While this sounds scary, it’s not as bad as you think.

I have a Centos 8 VM running on VirtualBox, so I started by cloning the Nchan GitHub repo to my home folder:

git clone https://github.com/slact/nchan

The README basically says: “grab the latest NGINX and Nchan sources, but during the configure stage add:”

... ./configure --add-module=path/to/nchan ...

To keep things simple, I’ll be building a single nginx binary. So the next step is to follow the instructions to build nginx from source. If you followed that link, it’s clear that the build process needs to be configured, but not exactly what those configuration parameters should be.

To make a long story short, I’ve found that the best way to construct the nginx configure command is to look at the command that was used to build the default nginx binary that shipped with the system. Yes, it’s actually possible to reconstruct it using the command line:

[smeans@localhost ~]$ nginx -V
nginx version: nginx/1.14.1
built by gcc 8.2.1 20180905 (Red Hat 8.2.1-3) (GCC)
built with OpenSSL 1.1.1 FIPS  11 Sep 2018 (running with OpenSSL 1.1.1g FIPS  21 Apr 2020)
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'

Nice! I created a subfolder in the nginx project called plugins and moved the nchan project folder there. So now I can run nginx ./configure with the copied configuration parameters above plus --add-module=plugins/nchan to build it with nchan support. I had to run make a few times, add missing dependencies, then retry the make. But once that was all done I was able to install it by running:

sudo make install

And that’s it! I ended up with an nginx binary that supports Nchan pub/sub, which I’ll be using for moggers. I’ll be posting about the architecture of that once we get it out of alpha, so stay tuned!

«