Search code examples
dockergoprotocol-buffersgrpcprotoc

How to use docker to generate grpc code based on go.mod versions?


Using the official golang docker image, I can use the protoc command to generate the x.pb.go and x_grpc.pb.go files. The problem is that it uses the latest versions, while I want to generate those using whichever version that is part of the go.mod file.

I tried to start from the golang image, then get my project's go.mod file, get the dependencies and try to generate from there. Here is my dockerfile:

FROM golang:1.15

WORKDIR /app

RUN apt-get update
RUN apt install -y protobuf-compiler

COPY go.* .
RUN go mod download
RUN go get all

RUN export PATH="$PATH:$(go env GOPATH)/bin"

RUN mkdir /api

Then I try to bind the volume of the .proto file and the /pb folder to output them, and use the protoc command again (I'm trying directly from the docker right now). Something like this:

protoc --proto_path=/api --go_out=/pb --go-grpc_out=/pb /api/x.proto

I'm getting this error though:

protoc-gen-go: program not found or is not executable
--go_out: protoc-gen-go: Plugin failed with status code 1.

My go.sum file has google.golang.org/protobuf v1.25.0 in it, so how come it is not found?


Solution

  • go.mod & go.sum are used for versioning when building go programs. This is not what you need here. You want the protoc compiler to use the correct plugin versions when running it against your .proto file(s).

    To install the desired protoc-gen-go (and protoc-gen-go-grpc if using gRPC) plugins, install them directly. Update your Dockerfile like so:

    FROM golang:1.15
    
    WORKDIR /app
    
    RUN apt-get update
    RUN apt install -y protobuf-compiler
    
    RUN GO111MODULE=on \
            go get google.golang.org/protobuf/cmd/[email protected] \
            google.golang.org/grpc/cmd/[email protected]
    
    # export is redundant here `/go/bin` is already in `golang` image's path
    # (and actual any env change here is lost once the command completes)
    # RUN export PATH="$PATH:$(go env GOPATH)/bin"
    
    RUN mkdir /api
    

    If you want the latest versions of either plugin, either use @latest - or drop the @ suffix