📑

gRPC - connect - Render でwebサービスを作ってみる:gRPC with connect on Docker

に公開

背景

gRPCもRemixも触ったことがないので、触ってみたいと思います。
gRPCのDocker環境構築は以前以下で実施しました。

また、以下でconnectを使っています。

connectを試した時は、はDockerではなく開発ホストで実行する流れだったので、Dockerizeしてみます。図としては開発ホストで実行する場合と変わらないですね。localでconnectを試した環境をlocal-connectDocker環境をdockerとして整理していこうと思います。

環境

動作確認した環境は以下です。

  • MacBook Pro
  • 14インチ 2021
  • チップ:Apple M1 Pro
  • メモリ:32GB
  • macOS:15.5(24F74)

構成の違い

Docker環境(docker)とローカル実行環境(local-connect)でのディレクトリ構成や役割の違いを、下記の表に整理しました。proto定義、ビジネスロジックの配置については共通化する必要がありそうです。

区分 docker環境 local-connect環境
proto定義 proto ディレクトリ greet ディレクトリ
ビジネスロジック gatewayserver ディレクトリ cmd ディレクトリ
その他 Docker関連ファイル buf関連ファイル
  • proto定義: gRPCのインターフェース定義を格納
  • ビジネスロジック: サーバやゲートウェイなど、アプリケーションの主要処理
  • その他: 各環境固有の補助的な設定やツール

tree比較

bufを使う場合は、トップレベルにサービスをおいたほうがパッケージ名が適切な状態になるなど事情があるようです。なので左をベースに作業をしようと思います。環境構築などはlocal-connectの記事を参照に準備します。

変更作業

以下の作業でDockerと連携ができました。

Dockerfile追加

# ビルド環境
FROM golang:alpine3.21 AS builder

# Dockerコンテナ内の作業ディレクトリ
WORKDIR /app

# go.modとgo.sumをDockerコンテナにコピー
COPY go.mod go.sum ./

# Docker コンテナでモジュールをダウンロード
RUN go mod download

# ソースコードをDockerコンテナにコピー
COPY . .

# gRPCサーバーをビルド
RUN go build -o bin/server ./cmd/server/main.go

# gRPCサーバの実行環境
FROM alpine:latest AS server

WORKDIR /app

COPY --from=builder /app/bin/server .

EXPOSE 50051

ENTRYPOINT ["./server"]

docker-compose.yamlを追加

services:
  server:
    build:
      context: .
      # Dockerfileのserverステージを使う
      target: server
    # ビルドイメージに名前をつける
    image: go-grpc-server
    ports:
      - "8080:8080"

サーバーの待受ポートを変更する

cmd/server/main.golocalhost:80800.0.0.0:8080にして外部からのアクセスを可能とする。

- "localhost:8080",
+ "0.0.0.0:8080",

動作確認

以下コマンドでサーバーを起動します

$ docker-compose up --build

後は以下コマンドで接続可能となります!
curl

$ curl \
        --header "Content-Type: application/json" \
        --data '{"name": "Jane"}' \
        http://localhost:8080/greet.v1.GreetService/Greet
{"greeting":"Hello, Jane!"}%    

grpccurl

$ grpcurl \
        -plaintext \
        -protoset <(buf build -o -) \
        -d '{"name": "Jane"}' \
        localhost:8080 greet.v1.GreetService/Greet
{
  "greeting": "Hello, Jane!"
}

goスクリプト

$ go run ./cmd/client/main.go 

2025/05/27 21:21:00 Hello, Jane!

まとめ

以上です!今日はDockerizeされたgoサーバーでconnectを使ってアクセスできることが確認できました。次はconnectをフロントエンドのtypescriptで繋いでみたいと思います。

Discussion