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.

1
2
3
cd ~/
mkdir test-module/
cd test-module/

screenshot 2

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

1
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.

1
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.
1
2
3
4
5
6
7
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.

1
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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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.

1
tree .

screenshot 22

Looking good.

Now start this OpenResty application.

1
nginx -p $PWD/

screenshot 24

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

1
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.

1
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.

1
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.

1
2
3
4
5
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.

1
nginx -p $PWD/ -t

screenshot 37

Good.

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

1
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.

1
curl 'http://127.0.0.1:8080/'

screenshot 41

Same behavior, just a little bit faster this time.

If you like this video, please subscribe to our channel. Thank you!

About This Article and Associated Video

This article and its associated video are both generated automatically from a simple screenplay file.

About The Author

Yichun Zhang is the creator of the OpenResty® open source project. He is also the founder and CEO of the OpenResty Inc. company. He contributed a dozen open source Nginx 3rd-party modules, quite some Nginx and LuaJIT core patches, and designed the OpenResty XRay platform.

Translations

We provide the Chinese translation for this article on blog.openresty.com.cn. We also welcome interested readers to contribute translations in other natural languages as long as the full article is translated without any omissions. We thank them in advance.

We are hiring

We always welcome talented and enthusiastic engineers to join our team at OpenResty Inc. to explore various open source software’s internals and build powerful analyzers and visualizers for real world applications built atop the open source software. If you are interested, please send your resume to talents@openresty.com . Thank you!