This repository contains an nginx module extension for invoking a call to a GRPC server.
This is code is based off of https://github.com/hashicorp/ngx_http_grpc_backend_module.git
This code is for example purposes only. It demonstrates both the ability to call Go code from C and the ability to make grpc calls. It is not production ready and should be considered inspiration only.
This module installs a helloworld directive inside the location block, and sets
the resulting $result variable.
http {
server {
listen 80;
server_name example.com;
location /hello {
helloworld $result world;
}
}
}This requires Golang to compile the dynamic library .so file. In
theory, this could be compiled in advance by a CI/CD system. There is no need
for the Golang runtime, since the runtime is compiled into the dynamic library.
The general flow is as follows:
-
A request comes into nginx that matches a defined
locationblock with ahelloworlddirective. -
nginx calls the
ngx_http_grpc_backendfunction with two arguments. -
The first argument is the variable in which to store the result (e.g.
$result). -
The second argument is the name of the variable to pass into the grpc Greeter.
-
The
ngx_http_grpc_backendcallsdlopenon the shared C library (the.sofile mentioned above), and executes the Go function by calling its symbol. -
The Go function makes a call with the Greeter grpc server
This installation guide uses ubuntu/debian. Adapt as-needed for other platforms.
- Golang >= 1.9
- Standard build tools, including GCC
-
Install the necessary build tools:
$ apt-get -yqq install build-essential curl git libpcre3 libpcre3-dev libssl-dev zlib1g-dev
-
Download and extract nginx source:
$ cd /tmp $ curl -sLo nginx.tgz https://nginx.org/download/nginx-1.12.2.tar.gz $ tar -xzvf nginx.tgz -
Download and extract the nginx development kit (ndk):
$ cd /tmp $ curl -sLo ngx_devel_kit-0.3.0.tgz https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz $ tar -xzvf ngx_devel_kit-0.3.0.tgz -
Download/clone this repository:
$ git clone https://github.com/myeh/ngx_http_grpc_backend_module /go/src/github.com/myeh/ngx_http_grpc_backend_module
-
Download/clone echo module:
$ git clone https://github.com/openresty/echo-nginx-module.git
-
Compile the Go code as a shared C library which nginx will dynamically load. This uses CGO and binds to the nginx development kit:
$ cd /tmp/ngx_http_grpc_backend_module/src $ mkdir -p /usr/local/nginx/ext $ CGO_CFLAGS="-I /tmp/ngx_devel_kit-0.3.0/src" \ go build \ -buildmode=c-shared \ -o /usr/local/nginx/ext/ngx_http_grpc_backend_module.so \ src/ngx_http_grpc_backend_module.go
This will compile the object file with symbols to
/usr/local/nginx/ext/nginx_http_grpc_backend_module.so. Note that the name and location of this file is important - it will bedlopened at runtime by nginx. -
Compile and install nginx with the modules:
$ cd /tmp/nginx-1.12.2 $ CFLAGS="-g -O0" \ ./configure \ --with-debug \ --add-module=/tmp/ngx_devel_kit-0.3.0 \ --add-module=/go/src/github.com/myeh/ngx_http_grpc_backend_module --add-module=/tmp/echo-nginx-module $ make $ make install
-
Add the required nginx configuration and restart nginx:
http { server { listen 80; server_name example.com; location /hello { helloworld $result world; echo $result; } } }
There is a sample Dockerfile and entrypoint which builds and runs this custom nginx installation with all required modules.
Once the docker container is up and running both the gRPC server and nginx will
be up and running. You will be able to run from your local machine
sh curl localhost:8080/hello