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

# Using the Lua SDK with NGINX

> This topic explains how to use the LaunchDarkly Lua server-side SDK with NGINX.

> For the complete documentation index, see [llms.txt](/llms.txt). For the full documentation snapshot, see [llms-full.txt](/llms-full.txt).

## Overview

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](/sdk/server-side/lua)
* Basic working knowledge of the LaunchDarkly [C++ server-side SDK](/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 SDKMake the source of the Lua SDK accessible to Open

RESTY. You can control imports with the `lua_package_path` directive.

For example:

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

## Preparing the C++ server-side SDKMake 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`.

<Note title="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.
</Note>

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