> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Using the Lua SDK with NGINX

This guide explains how to use our [Lua server-side SDK](https://github.com/launchdarkly/lua-server-sdk) with the [NGINX OpenResty framework](https://openresty.org).

OpenResty extends NGINX with [LuaJIT](https://luajit.org/), enabling complex control of [NGINX functionality](https://openresty-reference.readthedocs.io/en/latest/Lua_Nginx_API/). The OpenResty framework has substantial [commercial adoption](https://openresty.com/en/#mosaic-section).

Find a basic Dockerized app in the GitHub repository at [hello-nginx](https://github.com/launchdarkly/hello-nginx).

## Prerequisites

To complete this guide, you must have the following prerequisites:

* Basic working knowledge of the LaunchDarkly [Lua server-side SDK](/docs/sdk/server-side/lua)
* Basic working knowledge of the LaunchDarkly [C++ server-side SDK](/docs/sdk/server-side/c-c--)

The C++ server-side SDK is required because the Lua server-side SDK is implemented as a wrapper around the C++ server-side SDK.

## Preparing the Lua server-side SDK

Make the source of the Lua SDK accessible to OpenRESTY. You can control imports with the `lua_package_path` directive.

For example:

```nginx title="NGINX" lines wrap theme={null}
http {
    lua_package_path ";;/usr/local/openresty/nginx/scripts/?.lua;";
    ...
}
```

## Preparing the C++ server-side SDK

Make the source of the C++ server-side SDK accessible to the dynamic linker. The most convenient way to do this is to install the binary system-wide at `/usr/lib/libldserverapi.so`.

> [!CAUTION]
>
> **Configuring OpenSSL with OpenResty**
>
> OpenResty handles OpenSSL in specific ways. You may need to build the SDK from scratch instead of using our release artifacts in order to make OpenSSL work correctly.

## Ensuring correct initialization

The most important part of effective SDK usage is managing the lifetime of clients correctly. Because NGINX utilizes process-based concurrency, multiple clients initiate. If you accidentally initiate a client per request the application will be substantially slower, as the SDK has to download a fresh ruleset from LaunchDarkly.

Initialize each NGINX worker process exactly once for ideal operations. You can do this with the `init_worker_by_lua_file` directive. This directive executes a script when a process is freshly spawned. Client initialization should reside in this script. In the example below, this file is called `shared.lua`.

Here is an example of initialization logic:

```lua title="Lua SDK v2" lines wrap theme={null}
local ld = require("launchdarkly_server_sdk")
local os = require("os")

return ld.clientInit(os.getenv(sdk_key), 1000, config)
```

```lua title="Lua SDK v1.x" lines wrap theme={null}
local ld = require("launchdarkly_server_sdk")
local os = require("os")

local config = {
    key = os.getenv("YOUR_SDK_KEY")
}

return ld.clientInit(config, 1000)
```

Later we can use the result of this initialization process in other directives.

```lua title="Lua SDK v2" lines wrap theme={null}
local ld     = require("launchdarkly_server_sdk")
local client = require("shared")
local os     = require("os")

local context = ld.makeContext({
    user = {
      key = "abc"
    }
})

if client:boolVariation(context, "example-flag-key", false) then
    ngx.say("<p>feature launched</p>")
else
    ngx.say("<p>feature not launched</p>")
end
```

```lua title="Lua SDK v1.x" lines wrap theme={null}
local ld     = require("launchdarkly_server_sdk")
local client = require("shared")
local os     = require("os")

local user = ld.makeUser({
    key = "abc"
})

if client:boolVariation(user, "example-flag-key", false) then
    ngx.say("<p>feature launched</p>")
else
    ngx.say("<p>feature not launched</p>")
end
```

## Example: Feature flagged reverse proxy

This [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy) example demonstrates more complex interaction between multiple NGINX directives. You can use a reverse proxy to route traffic to multiple applications.

The example follows:

```nginx title="NGINX, with Lua SDK v2" maxLines=0 expandable lines wrap theme={null}
location / {
    set $proxy_host "";

    rewrite_by_lua_block {
        local ld     = require("launchdarkly_server_sdk")
        local client = require("shared")

        local context = ld.makeContext({
            user = {
              key = "abc"
            }
        })

        ngx.var.proxy_host = client:stringVariation(context, "example-flag-key", "10.0.0.0")
    }

    proxy_pass                       https://$proxy_host$uri;
    proxy_set_header Host            $proxy_host;
    proxy_set_header X-Forwarded-For $remote_addr;
}
```

```nginx title="NGINX, with Lua SDK v1.x" expandable lines wrap theme={null}
location / {
    set $proxy_host "";

    rewrite_by_lua_block {
        local ld     = require("launchdarkly_server_sdk")
        local client = require("shared")

        local user = ld.makeUser({
            key = "abc"
        })

        ngx.var.proxy_host = client:stringVariation(user, "example-flag-key", "10.0.0.0")
    }

    proxy_pass                       https://$proxy_host$uri;
    proxy_set_header Host            $proxy_host;
    proxy_set_header X-Forwarded-For $remote_addr;
}
```

<View title="Developer">
  > [!NOTE]
  >
  > **Want to know more? Start a trial.**
  >
  > Your 14-day trial begins as soon as you sign up. Get started in minutes using the in-app Quickstart. You'll discover how easy it is to release, monitor, and optimize your software.\
  > \\
  >
  > Want to try it out? [Start a trial](https://app.launchdarkly.com/signup).
</View>

<View title="Federal docs" />

<View title="EU docs" />
