Check out how OpenResty XRay helps organizations troubleshoot issues and optimize the performance of their applications.

Learn More LIVE DEMO

Today I’d demonstrate how to write your own Lua modules in your OpenResty applications, step by step.

screenshot 1

Let’s put our simple OpenResty application in a new directory named test-module.

cd ~/
mkdir test-module/
cd test-module/

screenshot 2

And then we create the sub-directory structure as always:

mkdir logs conf lua

screenshot 3

Note that unlike the “Hello World” example in our previous tutorial, we create a lua directory here to hold our Lua module files.

Now let’s create our own Lua module file named hello.lua under the lua sub-directory.

vim lua/hello.lua

We make the following edits:

  1. Declare the Lua module table _M.
  2. Then add a function named ‘greet’ to this Lua module.
  3. Finally, don’t forget to return the module table in the end.
local _M = {}

function _M.greet(name)
    ngx.say("Greetings from ", name)
end

return _M

That’s it! A very simple Lua module is done now.

Now it’s time to create the nginx.conf file.

vim conf/nginx.conf

And we make the following edits:

  1. We write the boilerplate configuration quickly.
  2. In the http configuration block, we should tell OpenResty where our Lua modules reside.
  3. Note the special variable $prefix is replaced by the nginx -p option value at runtime.
  4. Then we create an HTTP server listening on the 8080 port.
  5. And a root location with content_by_lua_block.
  6. Here we load our Lua module hello with the require built-in function.
  7. We call its greet function with an argument.
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    lua_package_path "$prefix/lua/?.lua;;";

    server {
        listen 8080 reuseport;

        location / {
            default_type text/plain;
            content_by_lua_block {
                local hello = require "hello"
                hello.greet("a Lua module")
            }
        }
    }
}

Let’s check the whole directory tree right now.

tree .

screenshot 22

Looking good.

Now start this OpenResty application.

nginx -p $PWD/

screenshot 24

Time to query our HTTP interface with the curl command-line utility.

curl 'http://127.0.0.1:8080/'

screenshot 25

Cool, our Lua module is working!

We can also test it in a web browser.

screenshot 28

If you see a 500 error page, then there must be an error in your Lua code.

In this case, you should check the error.log file under the logs sub-directory.

tail logs/error.log

screenshot 30

Here we don’t have any errors logged, as expected.

It’s worth noting that our Lua module is loaded in this first request and subsequent requests will just use the cached Lua module in memory. To avoid the extra overhead in the first request, we can preload the Lua module upon server startup.

To do this, we should edit the nginx.conf file a bit.

vim conf/nginx.conf

Inside the http {} block, we add an init_by_lua_block directive right there, and load our Lua module in this context.

    http {
        init_by_lua_block {
            require "hello"
        }
        ...

screenshot 34

The init_by_lua_block runs when the OpenResty server starts up.

Test if the configuration is sane.

nginx -p $PWD/ -t

screenshot 37

Good.

Now we reload the server by sending the HUP signal to the nginx master process.

kill -HUP `cat logs/nginx.pid`

screenshot 39

The master process’s ID is stored in this nginx.pid file.

Send the HTTP request again.

curl 'http://127.0.0.1:8080/'

screenshot 41

Same behavior, just a little bit faster this time.

If you like this tutorial, please subscribe to this blog site and our YouTube channel. Thank you!

About The Author

Yichun Zhang (Github handle: agentzh), is the original creator of the OpenResty® open-source project and the CEO of OpenResty Inc..

Yichun is one of the earliest advocates and leaders of “open-source technology”. He worked at many internationally renowned tech companies, such as Cloudflare, Yahoo!. He is a pioneer of “edge computing”, “dynamic tracing” and “machine coding”, with over 22 years of programming and 16 years of open source experience. Yichun is well-known in the open-source space as the project leader of OpenResty®, adopted by more than 40 million global website domains.

OpenResty Inc., the enterprise software start-up founded by Yichun in 2017, has customers from some of the biggest companies in the world. Its flagship product, OpenResty XRay, is a non-invasive profiling and troubleshooting tool that significantly enhances and utilizes dynamic tracing technology. And its OpenResty Edge product is a powerful distributed traffic management and private CDN software product.

As an avid open-source contributor, Yichun has contributed more than a million lines of code to numerous open-source projects, including Linux kernel, Nginx, LuaJIT, GDB, SystemTap, LLVM, Perl, etc. He has also authored more than 60 open-source software libraries.