🦮

gRPC x TypeScript を Docker で動かしてみた

2022/10/13に公開約3,300字

はじめに

gRPC x TypeScript を Docker コンテナ上で動かしたくなったので、docker compose 使って、試してみました。

中身は、先日書いたやつを流用したので、そっちも参考にしてもらえればと思います。
というか、そっちも読んでもらうこと前提で書いちゃってます。
加えて、そっちはメルカリのブログ読む前提で書いちゃってます。

gRPC x TypeScript のこと知りたい人はメルカリのブログをとりあえず、読んだら良いと思います。

この記事は、gRPC x TypeScript のことは大体わかるけど、サクッとコンテナ化するところ真似したいって人向けなのかなと思います。

コードは、optimisuke/hello-grpc-nodeに置いてます。

フォルダ構成

フォルダ構成はこんな感じにしました。

.
├── Makefile
├── README.md
├── backend
│   ├── config.ts
│   ├── index.ts
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   └── proto
├── bff
│   ├── config.ts
│   ├── helloClient.ts
│   ├── index.ts
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── proto
│   └── tsconfig.json
├── docker-compose.yml
├── package-lock.json
└── schema
    ├── gen
    ├── helloworld.proto
    ├── node_modules
    ├── package-lock.json
    └── package.json

proto は、backend と bff と並列に置くことにしました。

修正点

修正点は、少なくて、docker-compose.ymlを作った部分と、bff から backend にアクセスするときの URL を変更したくらい。

docker-compose.yml

docker-compose.ymlは、こんな感じにしました。

docker-compose.yml
version: "3.1"
services:
  bff:
    image: node:16
    volumes:
      - ./bff:/repo
    working_dir: /repo
    tty: true
    networks:
      - network
    ports:
      - 9000:9000
  backend:
    image: node:16
    volumes:
      - ./backend:/repo
    working_dir: /repo
    tty: true
    networks:
      - network
    ports:
      - 10000:10000
networks:
  network:

すごくシンプルです。backend もportsを指定してローカルからでも gRPC クライアントでアクセスできるようにしました。

URL

gRPC クライアントである bff の URL をこんな感じで変えました。

helloClient.ts
- import { host, port } from "./config";
+ import { host, port } from "./config";

- const serverURL = `localhost:${port}`;
+ const serverURL = `${host}:${port}`;
config.ts
export const port = 10000;
export const BFFPort = 9000;
+ export const host = 'backend';

Path

あと、細かいですが、proto から自動生成したコードのパスを変更してます。lint でエラーが出たところを修正してます。

Makefile

最後に、.protoファイルから、コード生成するときの Makefile をこんな感じにしました。

# Makefile
OUTPUT=gen
WORK_DIR=/repo
NPM_BIN=$(WORK_DIR)/schema/node_modules/.bin

GRPC_TOOL=$(NPM_BIN)/grpc_tools_node_protoc
TYPESCRIPT_PLUGIN=protoc-gen-ts=$(NPM_BIN)/protoc-gen-ts

COMMAND=$(GRPC_TOOL) --plugin=${TYPESCRIPT_PLUGIN} --js_out=import_style=commonjs,binary:$(OUTPUT) --grpc_out=grpc_js:$(OUTPUT) --ts_out=grpc_js:$(OUTPUT) -I . ./*.proto

.PHONY: protogen

test:
	echo `$(COMMAND)`

protogen:
	docker run --rm -it -v ${PWD}:$(WORK_DIR) -w $(WORK_DIR)/schema node:16 \
	/bin/bash -c "\
	npm install \
	&& rm -rf $(OUTPUT) \
	&& mkdir -p $(OUTPUT) \
	&& $(COMMAND) \
	&& rm -rf ../bff/proto \
	&& cp -r $(OUTPUT) ../bff/proto \
	&& rm -rf ../backend/proto \
	&& cp -r $(OUTPUT) ../backend/proto\
	"

backend と bff の Node のバージョンとそろえたほうが無難かなと思って、こっちもコンテナでやることにしました。
今回、自動生成したコードはシンプルに backend と bff のフォルダにコピーすることにしたので、最後やたらごちゃごちゃした感じになっちゃってます。本番で使うには、管理方法を検討する必要ありそうです。

おわりに

やったことはフォルダ構成考えて、docker-compose.yml書くくらいで、シンプルでしたが、地味に時間かかりました。
一つのpackage.jsonで管理してたものを分割する時、package.jsonが置かれてるフォルダの外にある自動生成したコードを参照しようとして、直接的じゃないエラーが出たり、Makefile のエラーがよくわからず、なかなか動かなかったり。
やったらできそうなことは、なかなか手を動かすのサボりがちですが、やってみてよかったかなーと思いました。

GitHubで編集を提案

Discussion

ログインするとコメントできます