WasmX/ngx_wasm_module documentation.
Consult INSTALL.md for instructions on how to build Nginx/OpenResty with this module.
Consult DIRECTIVES.md for a list of Nginx configuration directives and their effects.
Consult DEVELOPER.md for instructions on the development process and workflow.
See a term you are unfamiliar with? Consult the code lexicon.
For a primer on the code's layout and architecture, see the code layout section.
As the de-facto SDK for proxies in the WebAssembly world, the prominent way of extending Nginx with ngx_wasm_module is to write a Proxy-Wasm filter.
The Proxy-Wasm SDK is the initial focus of WasmX/ngx_wasm_module development and is still a work in progress. You can browse PROXY_WASM.md for a guide on Proxy-Wasm support in ngx_wasm_module.
For a reliable resource in an evolving ABI specification, you may also wish to consult the SDK source of the language of your choice in the Proxy-Wasm SDKs list.
ngx_wasm_module supports extending Nginx with WebAssembly in various
nginx.conf
contexts. Some of these contexts are referred to as "subsystems"
and provide additional sub-contexts:
wasm{}
: All directives specified within this block globally affect all WebAssembly execution throughout all other contexts.wasmtime{}
: all directives specified within this block will only take effect when ngx_wasm_module is compiled with Wasmtime.wasmer{}
: all directives specified within this block will only take effect when ngx_wasm_module is compiled with Wasmer.v8{}
: all directives specified within this block will only take effect when ngx_wasm_module is compiled with V8.
http{}
: this context is the "HTTP subsystem". All directives specified within this block apply to all enclosedserver{}
blocks. See http.stream{}
: this context is the "Stream subsystem". No directives are implemented for this subsystem in ngx_wasm_module yet.
All directives specified in a given context will be inherited by its nested sub-contexts, unless explicitly overridden.
For example:
# nginx.conf
wasm {
# this module is visible in all other contexts
module my_module /path/to/module.wasm;
# this setting applies to wasm execution in all other contexts
socket_connect_timeout 60s;
wasmtime {
# this flag only takes effect if wasmtime is in use
flag static_memory_maximum_size 1m;
}
wasmer {
# this flag only takes effect if wasmer is in use
flag wasm_reference_types on;
}
v8 {
# this flag only takes effect if v8 is in use
flag trace_wasm on;
}
}
http {
# this setting applies to wasm execution within the http{} block
wasm_socket_buffer_reuse off;
server {
# this setting overrides the above, but only in this server{} block
wasm_socket_buffer_reuse on;
location / {
# this setting overrides the wasm{} block setting, but only in this
# location{} block
wasm_socket_connect_timeout 5s;
# this setting references a module specified in the wasm{} block
proxy_wasm my_module;
# in this context:
# - buffer_reuse: on
# - connect_timeout: 5s
}
}
server {
# this setting overrides the wasm{} block setting, but only in this
# server{} block
wasm_socket_connect_timeout 10s;
location / {
# this setting references a module specified in the wasm{} block
proxy_wasm my_module;
# in this context:
# - buffer_reuse: off
# - connect_timeout: 10s
}
}
}
ngx_wasm_module implements a static "execution chain" model. This chain is a static list (i.e. determined at configuration time) of "WebAssembly operations" to be executed sequentially within a context (See Contexts).
In the http{}
subsystem, each location{}
block represents an entry-point
within an HTTP server/context. All location{}
blocks have an empty execution
chain by default. To add WebAssembly operations to an entry-point, one must
populate the execution chain by specifying directives within the desired
contexts.
For example:
# nginx.conf
http {
server {
listen 9000;
location / {
# run a proxy-wasm filter
proxy_wasm my_filter;
# run a proxy-wasm filter
proxy_wasm another_filter;
# call a WebAssembly function during the access phase
wasm_call access my_module check_something;
# call a WebAssembly function during the header_filter phase
wasm_call header_filter my_module check_something_else;
proxy_pass ...;
}
}
}
The execution chain runs WebAssembly code following the ordering of proxy_wasm
and wasm_call
directives, as well as the order of Nginx phases.
Let's assume that the above two Proxy-Wasm filters have the following callbacks implemented:
my_filter
implements 3 Proxy-Wasm callbacks to be executed at different Nginx phases:on_request_headers
,on_response_headers
,on_log
.another_filter
implements 2 callbacks:on_response_headers
,on_log
.
Given these filters and the above configuration, all requests matching /
will
process WebAssembly code in the following order:
- On the Nginx
rewrite
phase, it will: a. Call theon_request_headers
callback formy_filter
. - On the Nginx
access
phase, it will: a. Call thecheck_something
function frommy_module
. - On the Nginx
header_filter
phase, it will: a. Call theon_response_headers
callback formy_filter
. b. Call theon_response_headers
callback foranother_filter
. c. Call thecheck_something_else
function frommy_module
. - Finally, on the Nginx
log
phase, it will: a. Call theon_log
callback formy_filter
. b. Call theon_log
callback foranother_filter
.
Additionally, the execution chain of any context (http{}
, server{}
, or
location{}
) will be inherited by its sub-contexts, unless explicitly
overridden.
For example:
# nginx.conf
http {
# execute a proxy-wasm filter in all servers by default
proxy_wasm my_global_filter;
server {
listen 9000;
# override the execution chain in this server
# execute a proxy-wasm filter on all locations by default
proxy_wasm my_server_filter;
location /with-filter {
# inherits the "my_server_filter" execution
return 200;
}
location /no-filter {
# override the execution chain
# execute some WebAssembly during the access phase
wasm_call access my_module check_something;
# execute some WebAssembly during the header_filter phase
wasm_call header_filter my_module check_something_else;
proxy_pass ...;
}
}
server {
listen 9001;
location /with-filter {
# inherits the "my_global_filter" execution
return 200;
}
}
}
In the above example:
:9000/with-filter
: Inherits its execution chain from its parent block:server{}
. Runsmy_server_filter
.:9000/no-filter
: Overrides its execution chain. Runscheck_something
andcheck_something_else
in their respective phases.:9001/with-filter
: Inherits its execution chain from its grandparent block:http{}
. Runsmy_global_filter
.
You may also consult another description of the execution chain through the Filter Chains section, which focuses on the execution chain only through the lens of Proxy-Wasm filters.