How to call a Lua method on startup in NGINX? - nginx

I'm using Lua with NGINX. My code has a lua method called "rabbitmq.createExchange". I want to call this method, when nginx server starts.
I tried following code, but i failed with error "content_by_lua_block directive is not allowed here". Any solutions?
http {
lua_package_path '/app/nginx/src/?.lua;;';
server {
listen 4000;
include 'src/proj1.conf';
}
content_by_lua_block {
local rabbitmq = require 'src/rabbitmq.lua';
rabbitmq.createExchange("nginx", "topic");
}
}

You probably want init_by_lua_block - the content_by_lua_block directive is specifically for responding to a particular location, whereas the init_ version is for startup:
init_by_lua_block
syntax: init_by_lua_block { lua-script }
context: http
phase: loading-config
Similar to the init_by_lua directive except that this
directive inlines the Lua source directly inside a pair of curly
braces ({}) instead of in an NGINX string literal (which requires
special character escaping).
For instance,
init_by_lua_block {
print("I need no extra escaping here, for example: \r\nblah") }
(From the init_by_lua section, "Runs the Lua code [...] on the global Lua VM level when the Nginx master process (if any) is loading the Nginx config file.")

Related

Is it possible to have live reloading of lua scripts using openresty and docker?

I'm newish to LUA and want to practice some LUA scripting using nginx/openrestry.
Is there a workflow where I can use docker that runs openresty, and link my laptops filesystem to my docker container such that when I make a change to my lua script, I can quickly reload openrestry server so I can quickly see my lua changes take effect?
Any help or guidance would be appreciated.
You can disable Lua code cache — https://github.com/openresty/lua-nginx-module#lua_code_cache — add lua_code_cache off inside the http or server directive block. This is not actually “hot reload”, it's more like php request lifecycle:
every request served by ngx_lua will run in a separate Lua VM instance
You can think of it as if the code is hot–reloaded on each request.
However, pay attention to this:
Please note however, that Lua code written inlined within nginx.conf [...] will not be updated
It means that you should move all your Lua code from the nginx config to Lua modules and only require them:
server {
lua_code_cache off;
location /foo {
content_by_lua_block {
-- OK, the module will be imported (recompiled) on each request
require('mymodule').do_foo()
}
}
location /bar {
content_by_lua_block {
-- Bad, this inlined code won't be reloaded unless nginx is reloaded.
-- Move this code to a function inside a Lua module
-- (e.g., `mymodule.lua`).
local method = ngx.req.get_method()
if method == 'GET' then
-- handle GET
elseif method == 'POST' then
-- handle POST
else
return ngx.exit(ngx.HTTP_NOT_ALLOWED)
end
}
}
}
Then you can mount your Lua code from the host to the container using --mount or --volume: https://docs.docker.com/storage/bind-mounts/

'init_by_lua_block' directive not getting executed on nginx start

I wanted one of my lua script to get executed whenever nginx server starts or is reloaded. I tried using init_by_lua_block and init_by_lua_file directive but i dont see any log traces for the lua script in init_by_lua_block when i run the nginx docker. My http block looks like below. nginx.config is located in container path/etc/nginx/nginx.conf .
http {
sendfile on;
init_by_lua_block /etc/nginx/lua/init.lua;
include /etc/nginx/conf.d/proxy-config.conf;
}
Can anyone please tell me what I am missing here?
init_by_lua_block
syntax: init_by_lua_block { lua-script }
https://github.com/openresty/lua-nginx-module#init_by_lua_block
init_by_lua_block expects inlined Lua code, not a path to the Lua file.
Use dofile to execute Lua script:
init_by_lua_block {
dofile('/etc/nginx/lua/init.lua')
}
https://www.lua.org/manual/5.1/manual.html#pdf-dofile
or use init_by_lua_file:
init_by_lua_file /etc/nginx/lua/init.lua;
UPD:
You should use the NOTICE logging level (or higher) in init_by_lua_* directives because your error_log configuration is not yet applied in this phase:
Under the hood, the init_by_lua runs in the nginx configuration loading phase, so your error_log configuration in nginx.conf does not take effect until the whole configuration is loaded successfully (due to the bootstrapping requirements: the configuration loading MAY fail). And nginx initially uses a logger with the NOTICE filtering level upon startup which is effect in the whole first configuration loading process (but not subsequent configuration (re)loading triggered by the HUP signal).
https://github.com/openresty/lua-nginx-module/issues/467#issuecomment-82647228
So, use ngx.log(ngx.NOTICE, ...) (or ngx.WARN, ngx.ERR, etc. — see https://github.com/openresty/lua-nginx-module#nginx-log-level-constants) to see the output in the log.
Alternatively you can use print. It's equivalent to ngx.log(ngx.NOTICE, ...) under the hood: https://github.com/openresty/lua-nginx-module#print

Dynamic proxy_pass for stream

I'm trying to have openresty to reverse proxy TCP dynamicaly using lua.
For the start, I have :
stream {
server {
listen 9291;
set_by_lua_block $proxy '
ngx.var.proxy = "10.128.128.3:8291"
';
proxy_pass $proxy;
}
}
But openresty -t says:
nginx: [emerg] "set_by_lua_block" directive is not allowed here in /usr/local/openresty/nginx/conf/nginx.conf:129
I found many docs on dynamic proxy_pass, but all for 'http'.
Take a look at balancer_by_lua_block directive.
You will need to use ngx.balancer API within balancer_by_lua_block.
Read all docs carefully. There are a lot of smart details.
But all you need is here, just RTFM.

Nginx config invalid parameter even though it is in documentation

I am tryin to run nginx latest version with the following configuration, but I get nginx: [emerg] invalid parameter "route=bloomberg" in /etc/nginx/nginx.conf:13
docker run --rm -ti -v root_to_local_nginx_directory:/etc/nginx:ro -p 3080:80 --name=mynginx --entrypoint nginx nginx
# nginx.conf file inside root_to_local_nginx_directory
http {
map $cookie_route $route_from_cookie {
~.(?P<version>w+)$ $route;
}
split_clients "${remote_addr}" $random_route {
50% server bloomberg.com route=bloomberg;
* server yahoo.com route=yahoo;
}
upstream backend {
zone backend 64k;
server bloomberg.com route=bloomberg;
server yahoo.com route=yahoo;
sticky route $route_from_cookie $randomroute;
}
server {
# ...
listen 80;
location / {
proxy_set_header Host $host;
proxy_pass http://backend;
}
}
}
Why is this? According to the documentation this should be correct http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream.
The route=string parameter of the server directive within the upstream context is considered to be an enterprise-grade feature, and is thus only available through the commercial subscription, in NGINX Plus, not in OSS NGINX. (If you look closer into the documentation, you'll notice it's grouped together with the other parameters under a separate "available as part of our commercial subscription" subsection.)
Additionally, you're also trying to use some similar "server" parameters within the split_clients context as if they were actual directives interpreted by nginx, even though everything is supposed to be string literals in that context; it's unclear whether or not that part is responsible for any errors, but even if not, it's a bad style to introduce such confusion into your configuration.
References:
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server
http://nginx.org/en/docs/http/ngx_http_split_clients_module.html#split_clients
https://www.nginx.com/products/nginx/
The reason why you are seeing the error is because the split_clients module does not support the route parameter. Alternatively, you can do something along the lines:
upstream bloomberg {
server bloomberg.com route=bloomberg;
}
upstream yahoo {
server yahoo.com route=yahoo;
}
split_clients "${remote_addr}" $random_route {
50% bloomberg;
* yahoo;
}

Openresty torch module loading issue

I'm trying to use openresty with torch for a Rest api for a neural network.
First query works, any query after that fails.
Nginx Config
workers processes 1;
error_log logs/error.log;
events {
workers connections 1024
}
http {
server {
listen 5050;
location /{
default type text/html;
content_by_lua_file /home/yiftach/testFile.lua;
}
}
}
testFile.lua
require "nn"
local tensorA=torch.zeros(1,1)
ngx.say(tensorA:size()[1])
The error:
Lua entry thread aborted: runtime error: /home/yiftach/testFile.lua: attempt to index global 'torch' (a nil value)
Would appreciate any help
You didn't require the torch library.
Add local torch = require "torch" at the top.

Resources