Skip to content
This repository was archived by the owner on Jan 11, 2025. It is now read-only.

Commit f3fa785

Browse files
added more docs and examples
1 parent 61a730d commit f3fa785

16 files changed

+897
-26
lines changed

README.md

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,19 @@ Lua is a lightweight, high-level, multi-paradigm programming language designed p
4848

4949
> [wikipedia.org/wiki/Lua](https://en.wikipedia.org/wiki/Lua_(programming_language))
5050
51+
## Why this repo and not OpenResty?
52+
53+
| | nginx-lua | OpenResty |
54+
|--|--|--|
55+
| nginx latest version | `1.19.3` | `1.17.x` (last tested: `1.17.8`) |
56+
| Alpine supported |||
57+
| Amazon supported |||
58+
| CentOS supported |||
59+
| Debian supported |||
60+
| Fedora supported |||
61+
| Ubuntu supported |||
62+
| Windows supported |||
63+
5164
## Features
5265

5366
- Support for Lua.
@@ -62,35 +75,37 @@ Lua is a lightweight, high-level, multi-paradigm programming language designed p
6275

6376
## Typical Uses
6477

65-
Just to name a few:
66-
67-
* Mashup'ing and processing outputs of various Nginx upstream outputs (proxy, drizzle, postgres, redis, memcached, and etc) in Lua,
68-
* doing arbitrarily complex access control and security checks in Lua before requests actually reach the upstream backends,
69-
* manipulating response headers in an arbitrary way (by Lua)
70-
* fetching backend information from external storage backends (like redis, memcached, mysql, postgresql) and use that information to choose which upstream backend to access on-the-fly,
71-
* coding up arbitrarily complex web applications in a content handler using synchronous but still non-blocking access to the database backends and other storage,
72-
* doing very complex URL dispatch in Lua at rewrite phase,
73-
* using Lua to implement advanced caching mechanism for Nginx's subrequests and arbitrary locations.
74-
75-
The possibilities are unlimited as the module allows bringing together various
76-
elements within Nginx as well as exposing the power of the Lua language to the
77-
user. The module provides the full flexibility of scripting while offering
78-
performance levels comparable with native C language programs both in terms of
79-
CPU time as well as memory footprint thanks to LuaJIT 2.x.
80-
81-
Other scripting language implementations typically struggle to match this
82-
performance level.
78+
> Just to name a few:
79+
>
80+
> * Mashup'ing and processing outputs of various Nginx upstream outputs (proxy, drizzle, postgres, redis, memcached, and etc) in Lua,
81+
> * doing arbitrarily complex access control and security checks in Lua before requests actually reach the upstream backends,
82+
> * manipulating response headers in an arbitrary way (by Lua)
83+
> * fetching backend information from external storage backends (like redis, memcached, mysql, postgresql) and use that information to choose which upstream backend to access on-the-fly,
84+
> * coding up arbitrarily complex web applications in a content handler using synchronous but still non-blocking access to the database backends and other > storage,
85+
> * doing very complex URL dispatch in Lua at rewrite phase,
86+
> * using Lua to implement advanced caching mechanism for Nginx's subrequests and arbitrary locations.
87+
>
88+
> The possibilities are unlimited as the module allows bringing together various
89+
> elements within Nginx as well as exposing the power of the Lua language to the
90+
> user. The module provides the full flexibility of scripting while offering
91+
> performance levels comparable with native C language programs both in terms of
92+
> CPU time as well as memory footprint thanks to LuaJIT 2.x.
93+
>
94+
> Other scripting language implementations typically struggle to match this
95+
> performance level.
96+
>
97+
> - https://github.com/openresty/lua-nginx-module#typical-uses
8398
8499
## How to use this image
85100

86101
### Hosting some simple static content
87102

88103
```console
89-
$ docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx
104+
$ docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d fabiocicerchia/nginx-lua
90105
```
91106
Alternatively, a simple `Dockerfile` can be used to generate a new image that includes the necessary content (which is a much cleaner solution than the bind mount above):
92107
```dockerfile
93-
FROM nginx
108+
FROM fabiocicerchia/nginx-lua
94109
COPY static-html-directory /usr/share/nginx/html
95110
```
96111
Place this file in the same directory as your directory of content ("static-html-directory"), run `docker build -t some-content-nginx .`, then start your container:
@@ -108,18 +123,18 @@ Then you can hit `http://localhost:8080` or `http://host-ip:8080` in your browse
108123
### Complex configuration
109124

110125
```console
111-
$ docker run --name my-custom-nginx-container -v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
126+
$ docker run --name my-custom-nginx-container -v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro -d fabiocicerchia/nginx-lua
112127
```
113128
For information on the syntax of the nginx configuration files, see [the official documentation](http://nginx.org/en/docs/) (specifically the [Beginner's Guide](http://nginx.org/en/docs/beginners_guide.html#conf_structure)).
114129
If you wish to adapt the default configuration, use something like the following to copy it from a running nginx container:
115130
```console
116-
$ docker run --name tmp-nginx-container -d nginx
131+
$ docker run --name tmp-nginx-container -d fabiocicerchia/nginx-lua
117132
$ docker cp tmp-nginx-container:/etc/nginx/nginx.conf /host/path/nginx.conf
118133
$ docker rm -f tmp-nginx-container
119134
```
120135
This can also be accomplished more cleanly using a simple `Dockerfile` (in `/host/path/`):
121136
```dockerfile
122-
FROM nginx
137+
FROM fabiocicerchia/nginx-lua
123138
COPY nginx.conf /etc/nginx/nginx.conf
124139
```
125140
If you add a custom `CMD` in the Dockerfile, be sure to include `-g daemon off;` in the `CMD` in order for nginx to stay in the foreground, so that Docker can track the process properly (otherwise your container will stop immediately after starting)!
@@ -133,7 +148,7 @@ Out-of-the-box, nginx doesn't support environment variables inside most configur
133148
Here is an example using docker-compose.yml:
134149
```yaml
135150
web:
136-
image: nginx
151+
image: fabiocicerchia/nginx-lua
137152
volumes:
138153
- ./templates:/etc/nginx/templates
139154
ports:
@@ -164,15 +179,15 @@ This behavior can be changed via the following environment variables:
164179

165180
To run nginx in read-only mode, you will need to mount a Docker volume to every location where nginx writes information. The default nginx configuration requires write access to `/var/cache` and `/var/run`. This can be easily accomplished by running nginx as follows:
166181
```console
167-
$ docker run -d -p 80:80 --read-only -v $(pwd)/nginx-cache:/var/cache/nginx -v $(pwd)/nginx-pid:/var/run nginx
182+
$ docker run -d -p 80:80 --read-only -v $(pwd)/nginx-cache:/var/cache/nginx -v $(pwd)/nginx-pid:/var/run fabiocicerchia/nginx-lua
168183
```
169184
If you have a more advanced configuration that requires nginx to write to other locations, simply add more volume mounts to those locations.
170185

171186
### Entrypoint quiet logs
172187

173188
Since version 1.19.0, a verbose entrypoint was added. It provides information on what's happening during container startup. You can silence this output by setting environment variable `NGINX_ENTRYPOINT_QUIET_LOGS`:
174189
```console
175-
$ docker run -d -e NGINX_ENTRYPOINT_QUIET_LOGS=1 nginx
190+
$ docker run -d -e NGINX_ENTRYPOINT_QUIET_LOGS=1 fabiocicerchia/nginx-lua
176191
```
177192

178193
### User and group id
@@ -375,6 +390,20 @@ $ docker build \
375390
-f $DOCKERFILE .
376391
```
377392

393+
## Custom Builds
394+
395+
If you need to extend the functionality of the existing image, you could build your own version using the following command.
396+
For the list of values do refer to the [relative section](#compiled-version-details).
397+
398+
```console
399+
$ docker build
400+
--build-arg NGINX_BUILD_CONFIG=... \ # nginx build flags
401+
--build-arg BUILD_DEPS=... \ # packages needed for building phase
402+
--build-arg NGINX_BUILD_DEPS=... \ # packages needed for building phase by nginx
403+
--build-arg PKG_DEPS=... \ # packages available in final image
404+
-f $DOCKERFILE .
405+
```
406+
378407
## Image Labels
379408

380409
The image builds are labeled with various information. Here's an example of printing the labels using jq:

docs/examples/docker-compose.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
```yaml
2+
web:
3+
image: fabiocicerchia/ginx-lua
4+
volumes:
5+
- ./templates:/etc/nginx/templates
6+
ports:
7+
- "8080:80"
8+
environment:
9+
- NGINX_HOST=foobar.com
10+
- NGINX_PORT=80
11+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
```lua
2+
# set the Server output header
3+
more_set_headers 'Server: my-server';
4+
5+
# set and clear output headers
6+
location /bar {
7+
more_set_headers 'X-MyHeader: blah' 'X-MyHeader2: foo';
8+
more_set_headers -t 'text/plain text/css' 'Content-Type: text/foo';
9+
more_set_headers -s '400 404 500 503' -s 413 'Foo: Bar';
10+
more_clear_headers 'Content-Type';
11+
12+
# your proxy_pass/memcached_pass/or any other config goes here...
13+
}
14+
15+
# set output headers
16+
location /type {
17+
more_set_headers 'Content-Type: text/plain';
18+
# ...
19+
}
20+
21+
# set input headers
22+
location /foo {
23+
set $my_host 'my dog';
24+
more_set_input_headers 'Host: $my_host';
25+
more_set_input_headers -t 'text/plain' 'X-Foo: bah';
26+
27+
# now $host and $http_host have their new values...
28+
# ...
29+
}
30+
31+
# replace input header X-Foo *only* if it already exists
32+
more_set_input_headers -r 'X-Foo: howdy';
33+
```

docs/examples/lua-nginx-module.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
```nginx
2+
# set search paths for pure Lua external libraries (';;' is the default path):
3+
lua_package_path '/foo/bar/?.lua;/blah/?.lua;;';
4+
5+
# set search paths for Lua external libraries written in C (can also use ';;'):
6+
lua_package_cpath '/bar/baz/?.so;/blah/blah/?.so;;';
7+
8+
server {
9+
location /lua_content {
10+
# MIME type determined by default_type:
11+
default_type 'text/plain';
12+
13+
content_by_lua_block {
14+
ngx.say('Hello,world!')
15+
}
16+
}
17+
18+
location /nginx_var {
19+
# MIME type determined by default_type:
20+
default_type 'text/plain';
21+
22+
# try access /nginx_var?a=hello,world
23+
content_by_lua_block {
24+
ngx.say(ngx.var.arg_a)
25+
}
26+
}
27+
28+
location = /request_body {
29+
client_max_body_size 50k;
30+
client_body_buffer_size 50k;
31+
32+
content_by_lua_block {
33+
ngx.req.read_body() -- explicitly read the req body
34+
local data = ngx.req.get_body_data()
35+
if data then
36+
ngx.say("body data:")
37+
ngx.print(data)
38+
return
39+
end
40+
41+
-- body may get buffered in a temp file:
42+
local file = ngx.req.get_body_file()
43+
if file then
44+
ngx.say("body is in file ", file)
45+
else
46+
ngx.say("no body found")
47+
end
48+
}
49+
}
50+
51+
# transparent non-blocking I/O in Lua via subrequests
52+
# (well, a better way is to use cosockets)
53+
location = /lua {
54+
# MIME type determined by default_type:
55+
default_type 'text/plain';
56+
57+
content_by_lua_block {
58+
local res = ngx.location.capture("/some_other_location")
59+
if res then
60+
ngx.say("status: ", res.status)
61+
ngx.say("body:")
62+
ngx.print(res.body)
63+
end
64+
}
65+
}
66+
67+
location = /foo {
68+
rewrite_by_lua_block {
69+
res = ngx.location.capture("/memc",
70+
{ args = { cmd = "incr", key = ngx.var.uri } }
71+
)
72+
}
73+
74+
proxy_pass http://blah.blah.com;
75+
}
76+
77+
location = /mixed {
78+
rewrite_by_lua_file /path/to/rewrite.lua;
79+
access_by_lua_file /path/to/access.lua;
80+
content_by_lua_file /path/to/content.lua;
81+
}
82+
83+
# use nginx var in code path
84+
# CAUTION: contents in nginx var must be carefully filtered,
85+
# otherwise there'll be great security risk!
86+
location ~ ^/app/([-_a-zA-Z0-9/]+) {
87+
set $path $1;
88+
content_by_lua_file /path/to/lua/app/root/$path.lua;
89+
}
90+
91+
location / {
92+
client_max_body_size 100k;
93+
client_body_buffer_size 100k;
94+
95+
access_by_lua_block {
96+
-- check the client IP address is in our black list
97+
if ngx.var.remote_addr == "132.5.72.3" then
98+
ngx.exit(ngx.HTTP_FORBIDDEN)
99+
end
100+
101+
-- check if the URI contains bad words
102+
if ngx.var.uri and
103+
string.match(ngx.var.request_body, "evil")
104+
then
105+
return ngx.redirect("/terms_of_use.html")
106+
end
107+
108+
-- tests passed
109+
}
110+
111+
# proxy_pass/fastcgi_pass/etc settings
112+
}
113+
}
114+
```

docs/examples/lua-resty-cookie.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
```lua
2+
lua_package_path "/path/to/lua-resty-cookie/lib/?.lua;;";
3+
4+
server {
5+
location /test {
6+
content_by_lua '
7+
local ck = require "resty.cookie"
8+
local cookie, err = ck:new()
9+
if not cookie then
10+
ngx.log(ngx.ERR, err)
11+
return
12+
end
13+
14+
-- get single cookie
15+
local field, err = cookie:get("lang")
16+
if not field then
17+
ngx.log(ngx.ERR, err)
18+
return
19+
end
20+
ngx.say("lang", " => ", field)
21+
22+
-- get all cookies
23+
local fields, err = cookie:get_all()
24+
if not fields then
25+
ngx.log(ngx.ERR, err)
26+
return
27+
end
28+
29+
for k, v in pairs(fields) do
30+
ngx.say(k, " => ", v)
31+
end
32+
33+
-- set one cookie
34+
local ok, err = cookie:set({
35+
key = "Name", value = "Bob", path = "/",
36+
domain = "example.com", secure = true, httponly = true,
37+
expires = "Wed, 09 Jun 2021 10:18:14 GMT", max_age = 50,
38+
samesite = "Strict", extension = "a4334aebaec"
39+
})
40+
if not ok then
41+
ngx.log(ngx.ERR, err)
42+
return
43+
end
44+
45+
-- set another cookie, both cookies will appear in HTTP response
46+
local ok, err = cookie:set({
47+
key = "Age", value = "20",
48+
})
49+
if not ok then
50+
ngx.log(ngx.ERR, err)
51+
return
52+
end
53+
';
54+
}
55+
}
56+
```

0 commit comments

Comments
 (0)