OpenResty: Quando Nginx Da Solo Non Basta (e Non Vuoi un Backend Separato)

0 7a fg9zrzndo9l b

Hai mai avuto bisogno di aggiungere logica custom al tuo server web senza passare per un’applicazione backend separata? Magari rate limiting più sofisticato di quello che offre Nginx out-of-the-box, o autenticazione JWT direttamente sul reverse proxy, o manipolazione dinamica delle richieste.

La soluzione classica è mettere un’app Node/Python/Go dietro Nginx, con tutto il sovraccarico che questo comporta.

OpenResty risolve il problema in modo radicale: permette di scrivere quella logica dentro Nginx stesso, usando Lua.

Cos’è OpenResty?

OpenResty è una piattaforma web dinamica basata su Nginx e LuaJIT. Integra il core standard di Nginx con molte librerie Lua, un sacco di moduli Nginx di terze parti e la maggior parte delle loro dipendenze.

È sviluppato per aiutare gli sviluppatori a creare facilmente applicazioni web scalabili, web service e gateway web dinamici.

OpenResty consente di ottenere tutte le feature di Nginx, ma anche la possibilità di programmarlo dinamicamente. In poche parole, è come ottenere le performance di un’applicazione web programmata in C, ma scrivendo il codice con la semplicità di Lua.

OpenResty come piattaforma applicativa completa?

Sì. OpenResty permette di eseguire la logica della tua applicazione dentro il core Nginx ed è sviluppato in modo che tu non abbia nemmeno bisogno di un server applicativo separato a cui proxare le richieste.

Puoi persino interfacciarlo con database come MySQL, PostgreSQL, Redis e altri, attraverso i numerosi moduli sviluppati dalla community.

Ma chi usa OpenResty?

Cloudflare lo usa da anni, e buona parte dell’ecosistema Alibaba ci gira sopra. Non è una tecnologia di nicchia sperimentale: è roba usata in produzione pesante.

Secondo le statistiche di NetCraft, nel 2026 sono più di 42 milioni i siti che girano su piattaforma OpenResty.

Come funziona OpenResty?

Per capire OpenResty, dobbiamo fare un passo indietro e vedere come funziona Nginx.

Perché Nginx si distingue dagli altri server web?

I server web “tradizionali” (tipo il vecchio Apache in modalità prefork) funzionano così: arriva una richiesta, viene creato un processo o un thread per gestirla, finita la richiesta il processo muore o torna in pool.

Sembra logico, ma ha un problema enorme: se arrivano 10.000 richieste contemporaneamente, ti servono 10.000 processi/thread. Risultato: RAM esaurita, CPU in fiamme, server che si pianta.

Nginx ha rivoluzionato il gioco con un approccio chiamato event-driven non-blocking. Invece di assegnare un processo a ogni richiesta, Nginx ha pochi worker (di solito uno per CPU core) che gestiscono migliaia di connessioni contemporaneamente.

Come fa? Non si blocca mai ad aspettare. Quando una richiesta è in attesa di qualcosa (per esempio una risposta dal database, o la lettura di un file da disco), Nginx mette quella richiesta “in pausa” e va a servire le altre. Quando l’attesa è finita, riprende il lavoro lì dove l’aveva lasciato.

È come un cameriere bravissimo che, invece di stare fermo aspettando che il cuoco prepari il tuo piatto, va a prendere ordini agli altri tavoli, porta da bere a un terzo, e quando il cuoco suona la campanella torna da te. Risultato: serve 50 tavoli da solo, mentre un cameriere “tradizionale” ne servirebbe 5 con la stessa fatica.

Questa architettura è il motivo per cui Nginx regge carichi pazzeschi consumando pochissime risorse, ed è il motivo per cui è diventato il server web più usato al mondo per i siti ad alto traffico.

E qui entra in scena Lua

Tutto bello, ma Nginx “vanilla” ha un limite: la sua configurazione è statica. Scrivi le regole nel file nginx.conf, ricarichi Nginx, e quelle sono.

Se vuoi logica dinamica (tipo “se l’utente arriva da questo paese e ha questo cookie, allora fai X, altrimenti Y”) con Nginx puro o impazzisci con regole astruse o ti rassegni a mettere un’applicazione vera dietro.

OpenResty risolve la cosa integrando dentro Nginx un interprete Lua chiamato LuaJIT.

LuaJIT è una versione estremamente veloce di Lua, un linguaggio di scripting nato per essere embedded (cioè incorporato dentro altri programmi). È uno dei linguaggi dinamici più veloci in circolazione e, in molti casi, si avvicina alle performance del C.

L’integrazione è fatta bene: Lua eredita lo stesso modello non-blocking di Nginx. Quando il tuo codice Lua aspetta qualcosa (una query Redis, una chiamata HTTP esterna), non blocca il worker Nginx. Il worker continua a servire altre richieste finché l’operazione non è pronta.

Il ciclo di vita di una richiesta HTTP

immagine1

Quando una richiesta HTTP arriva su Nginx, non viene gestita “in un colpo solo”. Passa attraverso una serie di fasi, ognuna con un compito specifico.

Prima viene riscritta l’URL se necessario, poi si verifica se il client ha i permessi, poi si decide chi genera il contenuto, poi si modificano gli header della risposta, infine si invia il body al client.

OpenResty ti dà la possibilità di agganciarti a ognuna di queste fasi e iniettare il tuo codice Lua.

Le direttive principali che userai sono:

  • rewrite_by_lua_block — eseguito nella fase di rewrite. Qui puoi modificare l’URL, redirigere, leggere/scrivere variabili Nginx. Utile per logica di routing custom.
  • access_by_lua_block — eseguito nella fase di controllo accessi. Qui decidi se il client può proseguire o no. È il posto giusto per autenticazione, rate limiting, IP filtering custom.
  • content_by_lua_block — eseguito nella fase di generazione contenuto. Qui sei tu a generare la risposta. È l’equivalente di scrivere un endpoint applicativo.
  • header_filter_by_lua_block — eseguito mentre Nginx prepara gli header di risposta. Puoi aggiungere o modificare header al volo.
  • body_filter_by_lua_block — eseguito mentre Nginx invia il body della risposta. Puoi modificare il contenuto on-the-fly.
  • log_by_lua_block — eseguito quando la richiesta è già finita. Qui puoi loggare su Redis, Kafka o altri sistemi senza rallentare la risposta al client.

Perché OpenResty è potente

Pensa a cosa puoi fare con queste fasi a disposizione.

Vuoi un rate limiter basato su una logica custom (per esempio: 100 richieste al minuto per utente, ma 1000 per utenti premium)? Lo metti in access_by_lua_block.

Vuoi un’API che recupera dati da Redis e li restituisce come JSON? content_by_lua_block.

Vuoi loggare ogni richiesta su un sistema esterno per analytics in tempo reale? log_by_lua_block.

Tutto questo senza dover montare un’applicazione separata, senza overhead di rete interno e senza un altro processo da gestire.

E gira tutto con la stessa efficienza event-driven di Nginx. Il tuo codice Lua diventa parte integrante del worker Nginx. Niente context switch tra processi, niente serializzazione tra servizi, niente latenza aggiuntiva.

Quando NON usare OpenResty

Non è tutto oro quello che luccica.

Se ti basta un reverse proxy semplice, Nginx vanilla basta e avanza. Usare OpenResty in quel caso è overkill.

La learning curve è reale: devi conoscere Nginx, Lua e l’ecosistema dei moduli lua-resty-*.

Lua è un gran linguaggio — elegante, veloce, anche piacevole da scrivere. Ma è di nicchia, e questo ha conseguenze pratiche: trovare sviluppatori è più difficile rispetto a Python o JavaScript.

Il debugging è meno comodo rispetto ad altri ecosistemi. I log di Nginx sono il tuo principale alleato, e devi imparare a leggerli bene (la prima volta che ho dovuto debuggare un errore Lua dentro Nginx ci ho messo un’eternità a capire che stavo guardando il log sbagliato).

La community è più piccola: meno pacchetti pronti, meno tutorial, meno risposte online. A volte devi leggere direttamente il codice sorgente dei moduli.

OpenResty è pensato per stare all’edge: rate limiting, autenticazione, routing intelligente, manipolazione delle richieste, caching.

Se invece hai logica di business complessa — ORM pesanti, transazioni distribuite, workflow asincroni — è meglio usare un backend dedicato e mettere OpenResty davanti come gateway.

Insomma: OpenResty ha senso quando ti serve logica custom all’edge della tua infrastruttura, dove performance e latenza contano davvero, e quando hai la competenza per gestirlo.


Nel prossimo articolo vedremo come installarlo su Ubuntu e scrivere il primo hello world in LuaJIT.

Nel frattempo, vi lascio i link al sito ufficiale e al repo GitHub di OpenResty:


https://openresty.org/

https://github.com/openresty/openresty