Skip to content

Instantly share code, notes, and snippets.

@ergoz
Forked from fedej/Dockerfile
Created November 20, 2023 19:35
Show Gist options
  • Save ergoz/08a6a65487f973f65aaf88e871313dcd to your computer and use it in GitHub Desktop.
Save ergoz/08a6a65487f973f65aaf88e871313dcd to your computer and use it in GitHub Desktop.
gRPC-web with nginx proxy
js_import conf.d/grpcweb.js;
server {
listen 443 http2;
location @grpc-backend {
grpc_pass server:50051;
}
location @grpc-web {
js_header_filter grpcweb.grpc_text_headers;
js_body_filter grpcweb.grpc_text_response [buffer_type=buffer];
grpc_set_header TE "trailers";
grpc_set_header Content-Type "application/grpc";
grpc_hide_header Accept-Encoding;
grpc_hide_header Content-Length;
grpc_pass server:50051;
}
location /helloworld.Greeter/ {
js_header_filter grpcweb.grpc_text_headers;
if ($request_method != POST) {
return 200;
}
if ($http_content_type != "application/grpc-web-text") {
grpc_pass server:50051;
}
js_content grpcweb.grpc_text_content;
}
}
server {
listen 80;
location @grpc-backend {
grpc_pass server:50051;
}
location @grpc-web {
js_header_filter grpcweb.grpc_text_headers;
js_body_filter grpcweb.grpc_text_response [buffer_type=buffer];
grpc_set_header TE "trailers";
grpc_set_header Content-Type "application/grpc";
grpc_hide_header Accept-Encoding;
grpc_hide_header Content-Length;
grpc_pass server:50051;
}
location /helloworld.Greeter/ {
js_header_filter grpcweb.grpc_text_headers;
if ($request_method != POST) {
return 200;
}
if ($http_content_type != "application/grpc-web-text") {
grpc_pass server:50051;
}
js_content grpcweb.grpc_text_content;
}
}
version: "3.4"
services:
proxy:
build:
context: .
target: proxy
ports:
- "8080:80"
links:
- server
server:
build:
context: .
target: server
client:
build:
context: .
target: client
FROM node:16.14.2-alpine3.15 as client-builder
RUN apk update
RUN apk add git protoc
RUN mkdir /grpc
WORKDIR /grpc
RUN git clone -b 1.3.1 https://github.com/grpc/grpc-web
WORKDIR /grpc/grpc-web/net/grpc/gateway/examples/helloworld
RUN npm install
RUN wget -O /usr/local/bin/protoc-gen-grpc-web https://github.com/grpc/grpc-web/releases/download/1.3.1/protoc-gen-grpc-web-1.3.1-linux-x86_64
RUN chmod +x /usr/local/bin/protoc-gen-grpc-web
RUN protoc -I=. helloworld.proto --js_out=import_style=commonjs:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:.
RUN npx webpack client.js
FROM nginx:1.21.1-alpine as proxy
COPY --from=client-builder /grpc/grpc-web/net/grpc/gateway/examples/helloworld/dist/main.js /etc/nginx/html/dist/
COPY --from=client-builder /grpc/grpc-web/net/grpc/gateway/examples/helloworld/index.html /etc/nginx/html/
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY ./grpcweb.js /etc/nginx/conf.d/grpcweb.js
RUN echo -e "load_module modules/ngx_http_js_module.so;\n$(cat /etc/nginx/nginx.conf)" > /etc/nginx/nginx.conf
FROM python:3.9.12-slim as server
RUN apt update
RUN apt install -y --no-install-recommends git
RUN python -m pip install grpcio grpcio-tools
RUN mkdir /grpc
WORKDIR /grpc
RUN git clone -b v1.45.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
WORKDIR /grpc/grpc/examples/python/helloworld
CMD ["python", "greeter_server.py"]
FROM server as client
WORKDIR /grpc/grpc/examples/python/helloworld
RUN sed -i s/localhost:50051/proxy:443/g greeter_client.py
CMD ["bash", "-c", "while true; do python greeter_client.py; sleep 2; done"]
function grpc_text_headers(r) {
if (r.headersIn["Content-Type"] == "application/grpc-web-text") {
r.headersOut["content-type"] = "application/grpc-web-text";
r.headersOut["Access-Control-Allow-Origin"] = "*";
}
if (r.method === "OPTIONS") {
r.headersOut["Access-Control-Allow-Origin"] = "*";
r.headersOut["Access-Control-Allow-Credentials"] = "true";
r.headersOut["Access-Control-Allow-Methods"] = "POST, OPTIONS";
r.headersOut["Access-Control-Allow-Headers"] = "*";
r.headersOut["Access-Control-Max-Age"] = "1728000";
}
}
function grpc_text_response(r, data, flags) {
r.sendBuffer(data.toString("base64"), flags);
}
function grpc_text_content(r) {
if (r.headersIn["Content-Type"] == "application/grpc-web-text") {
let buff = Buffer.from(r.requestText, 'base64');
buff.copy(r.requestBuffer);
r.internalRedirect("@grpc-web");
} else {
r.internalRedirect("@grpc-backend");
}
}
export default {grpc_text_content, grpc_text_headers, grpc_text_response};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment