Using the Lua SDK with NGINX
Read time: 3 minutes
Last edited: Aug 17, 2023
This documentation is not updated to include changes due to LaunchDarkly's contexts feature.
To learn more about custom contexts, read Contexts.
Overview
This guide explains how to use our Lua server-side SDK with the NGINX OpenResty framework.
OpenResty extends NGINX with LuaJIT, enabling complex control of NGINX functionality. The OpenResty framework has substantial commercial adoption.
Find a basic Dockerized app in the GitHub repository at hello-nginx.
Prerequisites
To complete this guide, you must have the following prerequisites:
- Basic working knowledge of the LaunchDarkly Lua server-side SDK
- Basic working knowledge of the LaunchDarkly C/C++ server-side SDK
The C server-side SDK is required because the Lua server-side SDK is implemented via foreign function interface.
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:
http {lua_package_path ";;/usr/local/openresty/nginx/scripts/?.lua;";...}
Preparing the C/C++ server-side SDK
Make the source of the C/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
.
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:
local ld = require("launchdarkly_server_sdk")local os = require("os")local config = {key = os.getenv("sdk-key-123abc")}return ld.clientInit(config, 1000)
Later we can use the result of this initialization process in other directives.
local ld = require("launchdarkly_server_sdk")local client = require("shared")local os = require("os")local user = ld.makeUser({key = "abc"})if client:boolVariation(user, "flag-key-123abc", false) thenngx.say("<p>feature launched</p>")elsengx.say("<p>feature not launched</p>")end
Example: Feature flagged reverse proxy
This 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:
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, "flag-key-123abc", "10.0.0.0")}proxy_pass https://$proxy_host$uri;proxy_set_header Host $proxy_host;proxy_set_header X-Forwarded-For $remote_addr;}
Your 14-day trial begins as soon as you sign up. Learn to use LaunchDarkly with the app's built-in tutorial. You'll discover how easy it is to manage the whole feature lifecycle from concept to launch to control.
Want to try it out? Start a trial.