> ## 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:

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

## 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`.

<Danger>
  **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.
</Danger>

## 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:

<CodeGroup>
  ```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)
  ```
</CodeGroup>

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

<CodeGroup>
  ```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
  ```
</CodeGroup>

## 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:

<CodeGroup>
  ```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;
  }
  ```
</CodeGroup>

<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.<br /><br />

    Want to try it out? <a href="https://app.launchdarkly.com/signup">Start a trial</a>.
  </Note>
</View>

<View title="Federal docs" />

<View title="EU docs" />
