Skip to content

Instantly share code, notes, and snippets.

@encryptblockr
Forked from nginx-gists/errors.grpc_conf
Created June 18, 2022 22:24
Show Gist options
  • Save encryptblockr/e9b82fcc0e4906aad007fbfe33a1fc83 to your computer and use it in GitHub Desktop.
Save encryptblockr/e9b82fcc0e4906aad007fbfe33a1fc83 to your computer and use it in GitHub Desktop.
Deploying NGINX Plus as an API Gateway, Part 3: Publishing gRPC Services
# Standard HTTP-to-gRPC status code mappings
# Ref: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md
#
error_page 400 = @grpc_internal;
error_page 401 = @grpc_unauthenticated;
error_page 403 = @grpc_permission_denied;
error_page 404 = @grpc_unimplemented;
error_page 429 = @grpc_unavailable;
error_page 502 = @grpc_unavailable;
error_page 503 = @grpc_unavailable;
error_page 504 = @grpc_unavailable;
# NGINX-to-gRPC status code mappings
# Ref: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
#
error_page 405 = @grpc_internal; # Method not allowed
error_page 408 = @grpc_deadline_exceeded; # Request timeout
error_page 413 = @grpc_resource_exhausted; # Payload too large
error_page 414 = @grpc_resource_exhausted; # Request URI too large
error_page 415 = @grpc_internal; # Unsupported media type;
error_page 426 = @grpc_internal; # HTTP request was sent to HTTPS port
error_page 495 = @grpc_unauthenticated; # Client certificate authentication error
error_page 496 = @grpc_unauthenticated; # Client certificate not presented
error_page 497 = @grpc_internal; # HTTP request was sent to mutual TLS port
error_page 500 = @grpc_internal; # Server error
error_page 501 = @grpc_internal; # Not implemented
# gRPC error responses
# Ref: https://github.com/grpc/grpc-go/blob/master/codes/codes.go
#
location @grpc_deadline_exceeded {
add_header grpc-status 4;
add_header grpc-message 'deadline exceeded';
return 204;
}
location @grpc_permission_denied {
add_header grpc-status 7;
add_header grpc-message 'permission denied';
return 204;
}
location @grpc_resource_exhausted {
add_header grpc-status 8;
add_header grpc-message 'resource exhausted';
return 204;
}
location @grpc_unimplemented {
add_header grpc-status 12;
add_header grpc-message unimplemented;
return 204;
}
location @grpc_internal {
add_header grpc-status 13;
add_header grpc-message 'internal error';
return 204;
}
location @grpc_unavailable {
add_header grpc-status 14;
add_header grpc-message unavailable;
return 204;
}
location @grpc_unauthenticated {
add_header grpc-status 16;
add_header grpc-message unauthenticated;
return 204;
}
# vim: syntax=nginx
location /routeguide. {
auth_jwt realm=routeguide token=$http_auth_token;
auth_jwt_key_file my_idp.jwk;
grpc_pass grpc://routeguide_service;
}
# vim: syntax=nginx
log_format grpc_json escape=json '{"timestamp":"$time_iso8601",'
'"client":"$remote_addr","uri":"$uri","http-status":$status,'
'"grpc-status":$grpc_status,"upstream":"$upstream_addr"'
'"rx-bytes":$request_length,"tx-bytes":$bytes_sent}';
map $upstream_trailer_grpc_status $grpc_status {
default $upstream_trailer_grpc_status; # grpc-status is usually a trailer
'' $sent_http_grpc_status; # Else use the header, whatever its source
}
server {
listen 50051 http2; # In production, comment out to disable plaintext port
listen 443 http2 ssl;
server_name grpc.example.com;
access_log /var/log/nginx/grpc_log.json grpc_json;
# TLS config
ssl_certificate /etc/ssl/certs/grpc.example.com.crt;
ssl_certificate_key /etc/ssl/private/grpc.example.com.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1.2 TLSv1.3;
# Routing
location /routeguide. {
grpc_pass grpc://routeguide_service;
}
location /helloworld. {
grpc_pass grpc://helloworld_service;
}
# Error responses
include conf.d/errors.grpc_conf; # gRPC-compliant error responses
default_type application/grpc; # Ensure gRPC for all error responses
}
# Backend gRPC servers
#
upstream routeguide_service {
zone routeguide_service 64k;
server 127.0.0.1:10001;
server 127.0.0.1:10002;
server 127.0.0.1:10003;
}
upstream helloworld_service {
zone helloworld_service 64k;
server 127.0.0.1:20001;
server 127.0.0.1:20002;
}
# vim: syntax=nginx
log_format grpc_json escape=json '{"timestamp":"$time_iso8601",'
'"client":"$remote_addr","uri":"$uri","http-status":$status,'
'"grpc-status":$grpc_status,"upstream":"$upstream_addr"'
'"rx-bytes":$request_length,"tx-bytes":$bytes_sent}';
map $upstream_trailer_grpc_status $grpc_status {
default $upstream_trailer_grpc_status; # grpc-status is usually a trailer
'' $sent_http_grpc_status; # Else use the header, whatever its source
}
server {
listen 50051 http2; # Plaintext
# Routing
location /routeguide. {
grpc_pass grpc://routeguide_service;
health_check type=grpc grpc_status=12; # 12=unimplemented
}
location /helloworld. {
grpc_pass grpc://helloworld_service;
health_check type=grpc grpc_status=12; # 12=unimplemented
}
}
# Backend gRPC servers
#
upstream routeguide_service {
zone routeguide_service 64k;
server 127.0.0.1:10001;
server 127.0.0.1:10002;
server 127.0.0.1:10003;
}
upstream helloworld_service {
zone helloworld_service 64k;
server 127.0.0.1:20001;
server 127.0.0.1:20002;
}
# vim: syntax=nginx
# Service-level routing
location /routeguide.RouteGuide/ {
grpc_pass grpc://routeguide_service_default;
}
# Method-level routing
location = /routeguide.RouteGuide/RouteChat {
grpc_pass grpc://routeguide_service_streaming;
}
# vim: syntax=nginx
# This Dockerfile runs the helloworld server from
# https://grpc.io/docs/quickstart/go.html
FROM golang
RUN go get -u google.golang.org/grpc
WORKDIR $GOPATH/src/google.golang.org/grpc/examples/helloworld
EXPOSE 50051
CMD ["go", "run", "greeter_server/main.go"]
# This Dockerfile runs the RouteGuide server from
# https://grpc.io/docs/tutorials/basic/python.html
FROM python
RUN pip install grpcio-tools
RUN git clone -b v1.14.x https://github.com/grpc/grpc
WORKDIR grpc/examples/python/route_guide
EXPOSE 50051
CMD ["python", "route_guide_server.py"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment