2

I am using OpenResty Nginx, and have a snippet of Lua script in the Nginx conf. (sample below, but truncated for brevity). This works fine when it is in the nginx.conf file.

rewrite_by_lua '

    -- Load Memcached module
    local memcached = require "resty.memcached"
    local memc, err = memcached:new()
    if not memc then
        ngx.log(ngx.ERR, "Failed to instantiate memc: ", err)
        return
    end
'

However, if I extract this script in to a file, memcached.lua and then include it in the nginx config with rewrite_by_lua_file, I am unable to restart nginx and get notifications about syntax errors such as:

unexpected "," in /etc/nginx/sites-enabled/memcached.lua

unknown directive "--" in /etc/nginx/sites-enabled/memcached.lua

If I remove the ngx.log line completely the syntax error disappears.

How come the syntax is valid in the nginx conf but not when I extract it to a separate file? I've read somewhere about bytecode but not sure if that is related?

EDIT

Here is the full output of the .lua file. This exact code works if it's embedded directly in to the nginx.conf file via rewrite_by_lua

cat /etc/nginx/sites-enabled/memcached.lua

-- Define Memcached key
local memcached_key = "saas_" .. ngx.var.host

-- Load Memcached module
local memcached = require "resty.memcached"
local memc, err = memcached:new()
if not memc then
    ngx.log(ngx.ERR, "Failed to instantiate memc: ")
end

-- Set Memcached timeout
memc:set_timeout(1000)

-- Connect to Memcached daemon
local ok, err = memc:connect("127.0.0.1", 11211)
if not ok then
    ngx.log(ngx.ALERT, "Failed to connect to Memcached: ", err)
end

-- Query for branch name in Memcached
local branch, flags, err = memc:get(memcached_key)
if err then
    ngx.log(ngx.NOTICE, "Failed to get account from Memcached: ", err)
end

-- If branch not found in Memcached, ask MySQL instead
if not branch then

    -- Load MySQL module
    local mysql = require "resty.mysql"
    local db, err = mysql:new()
    if not db then
        ngx.log(ngx.ALERT, "Failed to instantiate MySQL: ", err)
        return
    end

    -- Set MySQL timeout
    db:set_timeout(1000) -- 1 sec

    -- Connect to MySQL daemon
    local ok, err, errno, sqlstate = db:connect{
        path = "/var/run/mysqld/mysqld.sock",
        database = "dbname",
        user = "dbuser",
        password = "dbpass" }
    if not ok then
        ngx.log(ngx.ALERT, "Failed to connect to DB: ", err, ": ", errno, " ", sqlstate)
        return
    end

    -- Define subdomain string by extracting it from the http hostname
    local subdomain = string.match(ngx.var.host, "([%w-]+).")
    local quoted_subdomain = ngx.quote_sql_str(subdomain)

    -- Execute an SQL query to get the branch name based on the subdomain
    local sql = "SELECT branch FROM saas_account WHERE account = " .. quoted_subdomain
    local res, err, errno, sqlstate = db:query(sql, 1)
    if not res then
        ngx.log(ngx.ALERT, "Bad result from DB: ", err, ": ", errno, ": ", sqlstate, ".")
        return
    end

    -- Check we got a result
    if not res[1] then
        ngx.log(ngx.NOTICE, "No docroot was returned for subdomain: ", subdomain)
        ngx.var.branch = "chaletops"
    -- Assign the result from MySQL to the Nginx variable
    else
        ngx.var.branch = res[1].branch

        -- Store the result from MySQL back in to Memcached with a lifetime of 1 hour (3600 seconds)
        local ok, err = memc:set(memcached_key, ngx.var.branch, 3600)
        if not ok then
            ngx.log(ngx.WARN, "Failed to set branch in Memcached: ", err)
            -- return
        end
    end

    -- Save MySQL KeepAlive connection
    local ok, err = db:set_keepalive(10000, 100)
    if not ok then
        ngx.log(ngx.ALERT, "Cannot set MySQL keepalive: ", err)
        return
    end

    ngx.log(ngx.NOTICE, "Loading branch from MySQL: ", ngx.var.branch)

-- Else we did get a result from Memcached
else

    -- Assign the result from Memcached to the Nginx variable
    ngx.var.branch = branch

    ngx.log(ngx.NOTICE, "Loading branch from Memcached: ", ngx.var.branch)

end

-- Save Memcached KeepAlive connection
local ok, err = memc:set_keepalive(10000, 100)
if not ok then
    ngx.log(ngx.ALERT, "Cannot set Memcached keepalive: ", err)
    -- return
end

SOLUTION

TL:DR - put the .lua file outside of your Nginx configuration directory.

After being asked to post the exact error messages, I had to recreate the problem. For reference and Google searchers the error messages are like this:

2015/12/17 10:04:02 [emerg] 6903#0: unexpected "," in /etc/nginx/sites-enabled/memcached.lua:18

This time I copied the Lua code out of my nginx.conf and put it in a file called memcached.lua and saved it in my project directory. I then added the following include to my nginx.conf in place of the Lua script:

rewrite_by_lua_file /path/to/my/project/memcached.lua;

Immediately it starts working!

Previously I had included it by symlinking it from my project directory in to /etc/nginx/sites-enabled/memcached.lua (assuming it would be better for it to actually live alongside the .conf that includes it) and then just used rewrite_by_lua_file memcached.lua; as it was relative the .conf file.

So I initially wondered if it was because the rewrite_by_lua_file function could not follow symlinks or something, but then it dawned on me that it was nothing to do with the Lua include statement, but OBVIOUSLY (now!) because of the symlink being in /etc/nginx/sites-enabled so Nginx was automatically trying to load the file as though it was a normal Nginx configuration file.

This is because Nginx (on Ubuntu/Linux Mint) is configured to import all config files using the path /etc/nginx/sites-enabled/* in to it's main config.

I think the reason I made this simple error is that on later versions of Ubuntu with Apache, a similar process happens but with Apache (which I am much more used to) you have an include path of /etc/nginx/sites-enabled/*.conf - i.e. it specifically requires a .conf file extension, which is why I incorrectly assumed that Nginx would not try to include my .lua file.

Benr77
  • 155
  • 1
  • 10

0 Answers0