Extending-NGINX-with-JavaScript-TP151

Extending NGINX with JavaScript (NJS)

Problem

You are using NGINX as application server, load balancer, etc. but the normal configuration is too limited? For example, you want to redirect to a language-specific URL through the accept-language header?

Solution

NGINX has a module that allows to use a subset of JavaScript (NJS) to process requests. This uses its own engine, since V8 & Co are not fast enough. The NJS code is converted to bytecode, which makes the execution very fast (I measured the example of redirecting with "accept-language" in the network tab with 0ms).

Example

Since the official documentation is unfortunately incomplete or outdated, here are the most important points as Docker setup:

First, it needs a JavaScript file. SinceNJS is a subset of JS, you must partly work with older JS constructs (old for loop, no const/let, etc.). Fat Arrow functions do work however. Just try what works!
nginxLib.js

function hello(r) {
    r.return(200, "Hello world!");
}

export default { hello };
Next, the nginx.conf must load this file and execute it at a location:
default.conf

js_import /etc/nginx/conf.d/nginxLib.js;

server {
    # ...
    location = / {
        js_content nginxLib.hello;
    }
    # ...
}

Copy these files in the Docker file and also add a load_module statement to the root nginx.conf.

Dockerfile

FROM nginx:1.21.1-alpine

# ...
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY ./nginxLib.js /etc/nginx/conf.d/nginxLib.js

# Load njs module for nginx by inserting a line at the top of the root nginx.conf
RUN echo -e "load_module modules/ngx_http_js_module.so;\n$(cat /etc/nginx/nginx.conf)" > /etc/nginx/nginx.conf
# ...

The load_module statement unfortunately has to be part of the root nginx.conf because the configuration is hierarchical (e.g. global - http - server). Since the root nginx.conf imports our default.conf in the http section, all our statements are also in the http section. However, the load_module statement must be defined in the global section.

Extending-NGINX-with-JavaScript-NJS-Visual

Further Aspects

---

Author: Santo Pfingsten / Senior Software Architect / Office Leipzig

Cookie Settings

This website uses cookies to personalize content and ads, provide social media features, and analyze website traffic. In addition, information about your use of the website is shared with social media, advertising, and analytics partners. These partners may merge the information with other data that you have provided to them or that they have collected from you using the services.

For more information, please refer to our privacy policy. There you can also change your cookie settings later on.

contact icon

Contact us now