Getting Started with Lua
Introduction
Welcome to the first lesson in our "Extending NGINX with Lua and OpenResty" course! In this lesson, we'll take our first steps in combining the power of NGINX with the flexibility of Lua scripting through OpenResty. By the end of this lesson, you'll understand how to embed Lua code directly in NGINX configuration files and use it to generate dynamic responses, control access, and create custom logging.
Why Lua in NGINX?
Lua is a lightweight, fast scripting language designed to be embedded into other programs. OpenResty is an NGINX-based distribution that embeds Lua into the NGINX request lifecycle (via the Lua module and a set of supporting libraries), so you can run Lua code inside NGINX worker processes while handling requests.
NGINX is excellent at serving static content and proxying requests, but its configuration language is primarily declarative—great for routing and policies, less ideal for custom logic. With OpenResty + Lua, we can add that missing “programmable layer” directly at the edge, without introducing a separate application server for many use cases.
This combination enables:
- Dynamic content generation without external applications
- Custom authentication and authorization logic
- Request transformation and validation
- Advanced logging and metrics collection
- High performance, because Lua executes within the NGINX worker process
Understanding OpenResty Directives and Execution Phases
OpenResty provides several directives that let us inject Lua code at different stages of request processing. Think of NGINX request handling as a series of phases, and each directive gives us access to a specific phase—with different capabilities and restrictions depending on when it runs.
The three main directives we'll work with are:
access_by_lua_block: Runs during the access phase, before content generation; perfect for authentication and authorizationcontent_by_lua_block: Executes during the content phase to generate responseslog_by_lua_block: Executes during the log phase after the response is sent; ideal for logging and metrics
Execution order (high level):
access_by_lua_block: Runs early, before content generationcontent_by_lua_block: Generates the response bodylog_by_lua_block: Runs after the response is sent
It’s important to remember that each phase has restrictions on which OpenResty API functions you can use. For example, output functions like ngx.say() only work in phases where you're building the response, and won’t work in the log phase since the response has already been sent.
