gRPC-Web をやってみるための環境を作る
gRPC-Web を改めてやってみようと思ったがかなり変わっていそうなので、まず環境を Docker で作る。
開発環境
- Windows 10 Pro バージョン20H2
- docker desktop 3.3.3
- WSL2 のディストリビューションは Ubuntu 20.04
参考文献
環境構築にあたり、まず gRPC-Web の 公式サイト は情報が古くてあまり参考にならなかった。
よって本記事では下記記事を大いに参考にした。
本文
最初に完成品は下記にあるので細かいことは実際に動かしてみてほしい。
https://gitlab.com/k1350/daybreak_grpc_web_test/-/tree/helloworld
protocol buffer の内容は以前やった Go 言語で gRPC をはじめてみる - 環境構築編 と同じで、サーバーサイドのコードも同じである。
今回から Docker コンテナで動かすユーザーを root 以外にするようにしたので Dockerfile は多少違ったり、protoc コマンドの内容を最適化したりしたが、基本的には前にやったことと同じ。
よって本記事ではクライアントサイドと Envoy に着目する。
gRPC-Web protoc plugin のインストールとコンパイル
以前やったときは Go 用のコンパイルだけすればよかったが、今回は js 用のコンパイルが必要なので、Protocol Buffers をコンパイルする環境に追加のプラグインが必要になる。
2021/06/06現在、gRPC-Web の公式サイトの Basics tutorial を見るとコンパイルしろと書いてあるのだが、そんなことはしなくていい。
gRPC-Web のリポジトリ の README.md に記載されているが、ちゃんと公式にバイナリが配布されているので使う。
前回までと変える点は下記 Dockerfile では 11-13 行目で、配布されているバイナリをダウンロードして protoc-gen-grpc-web という名前で /usr/local/bin にコピーし、実行権限を付与する。
|
|
protoc-gen-grpc-web という名前は一字一句違わないように気を付けること。(ここで typo して、後で protoc-gen-grpc-web コマンドが見つからないというエラーになりハマった。)
これで gRPC-Web 用のコンパイルが可能となる。
コンパイルコマンドは gRPC-Web のリポジトリ の README に記載の通り、下記のようになる。
protoc -I=proto/api \
--js_out=import_style=commonjs:./client/generated/helloworld \
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:./client/generated/helloworld \
proto/api/helloworld.proto
これは proto/api/helloworld.proto を commonjs スタイルでコンパイルし、./client/generated/helloworld に出力するというコマンドである。
他のオプションは gRPC-Web のリポジトリ の README に書いてある。
クライアントサイド
次はクライアントサイドの実装だが、本記事はあくまでも環境構築の内容だし参考記事を丸パクリしたので流す。こんな感じ。
クライアントサイドを実行するための環境構築は参考記事には書いていなかったので取り扱う。
今回は webpack でコードをまとめて、http-server というやつでサーバーを立てることにした。
当初は参考記事の通り yarn でサーバーを立てようとしたのだが、私の知識不足でうまくいかなかったので http-server にした。
Dockerfile はシンプルに下記の通り。ほとんど素の node イメージのまま。
# 2021/06/06 現在の最新バージョン
FROM node:16-alpine3.11
# デフォルトで入っている node ユーザーを使う
USER node
WORKDIR /client
EXPOSE 8081
このコンテナ内で npm install するための package.json が下記の通り。
{
"name": "grpc-web-client",
"dependencies": {
"google-protobuf": "^3.17.2",
"grpc-web": "1.2.1"
},
"devDependencies": {
"browserify": "^17.0.0",
"http-server": "^0.12.3",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0"
}
}
Basics tutorial にもこんな内容が書いてあるのだが、2021/06/06現在の gRPC-Web の最新バージョンは 1.2.1 なのに 0.4.0 が指定してあって本当に古いので要注意。
当然コンパイルに使ったバージョンと同じバージョンでないとうまく動かない。
あとはコンテナ起動後に
npm install
npx webpack --mode=development ./client.js
npx http-server -p 8081
という内容を実行すればよいので、これを scripts/make.sh という名前に記述しておき、docker-compose.yml のクライアント部分は下記のようになる。
client:
container_name: client
image: grpc_web_client:1.0
build:
context: ./client/build
volumes:
- type: bind
source: "./client"
target: "/client"
ports:
- "8081:8081"
tty: true
depends_on:
- proto
- server
command:
sh -c "chmod -R +x ./scripts/ && ./scripts/make.sh && /bin/sh"
Envoy
最後に gRPC-Web を実行するために必要なプロキシである Envoy だが、これについてもほぼ参考記事を丸パクリしたので流す。設定ファイルは こんな感じ で、docker-compose.yml の Envoy 部分は下記のようになる。
envoy:
container_name: envoy
image: envoyproxy/envoy:v1.18.3
ports:
- "10000:10000"
volumes:
- type: bind
source: "./proxy/envoy.yaml"
target: "/etc/envoy/envoy.yaml"
実行
完成品の README に記載の通りに実行し、localhost:8081 にアクセスすると画面に “Hello World” と出るはず。
余談なのだが先日 新しい docker compose なる記事を見て、“docker-compose” を “docker compose” に読み替えて本環境構築を行っていたところバグを踏み抜いてハマってしまった。
issue 立ってるのだが “docker compose build” は build arg を反映しないので、2021/06/06現在ではまだ “docker-compose” を使うほうがハマらないと思う。
今回はこれで終わり。