Problem
Ihr nutzt NGINX als Application Server, Load Balancer, etc. aber die Möglichkeiten der normalen Konfiguration reichen nicht aus? Beispielsweise wollt ihr durch den accept-language-Header eine Weiterleitung auf eine sprachspezifische URL vornehmen?
Lösung
NGINX hat ein Modul, welches es erlaubt, ein Subset von JavaScript (NJS) zu nutzen, um Anfragen zu verarbeiten. Dabei wird eine eigene Engine genutzt, da V8 & Co nicht schnell genug sind. Der NJS-Code wird dabei zu Bytecode gewandelt, was die Ausführung sehr schnell macht (Das Beispiel "accept-language"-Weiterleitung habe ich im Netzwerktab mit 0ms gemessen).
Beispiel
Da die offizielle Doku leider unvollständig oder veraltet ist, hier kurz die wichtigsten Punkte in Form eines Docker Setups:
nginxLib.js
function hello(r) {
r.return(200, "Hello world!");
}
export default { hello };
default.conf
js_import /etc/nginx/conf.d/nginxLib.js;
server {
# ...
location = / {
js_content nginxLib.hello;
}
# ...
}
Im Dockerfile kopiert man diese Dateien und ergänzt zusätzlich die root nginx.conf um ein load_module Statement.
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
# ...
Das load_module Statement muss leider in die root nginx.conf, da die Konfiguration hierarchisch aufgebaut ist (z. B. global - http - server). Da die root nginx.conf im Bereich http unsere default.conf importiert, sind all unsere Statements auch im Bereich http. Das load_module Statement muss jedoch im globalen Bereich definiert werden.
Weiterführende Aspekte
- Doku: https://nginx.org/en/docs/njs/index.html
- Video: https://www.youtube.com/watch?v=Jc_L6UffFOs
- Accept-Language-Beispiel: https://gist.github.com/SantoJambit/2fdcf696645dc7ef72ca0e70ebbd7b4a
---
Autor: Santo Pfingsten / Senior Software Architect / Standort Leipzig
Toilet Paper #151 als Download: NGINX mit JavaScript (NJS) erweitern (PDF)
Lust, das nächste ToiletPaper zu schreiben? Jetzt bei jambit bewerben!