构建一个包含多个Proto文件的Docker – 找不到Proto文件

huangapple go评论128阅读模式
英文:

Building a Docker with Multiple Proto - Proto File not found

问题

我遇到了一个问题,无法构建包含多个proto文件(服务器和文本)的Dockerfile。服务器proto文件位于Dockerfile目录中,但文本proto文件位于Dockerfile的父目录中。因此,我在父目录中构建Dockerfile以将文本proto文件复制到Docker构建中。

尽管我将proto/text.proto复制到与server/proto/server.proto相同的位置,但Docker构建仍然报错proto/text.proto: File not found.

以下是我所有的文件:

DockerFile

  1. FROM --platform=linux/x86_64 golang:1.19.3-bullseye
  2. # Install grpc
  3. RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 && \
  4. go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
  5. WORKDIR /app
  6. COPY server/. /app
  7. COPY proto/text.proto /app/proto/text.proto
  8. # Install protoc and zip system library
  9. RUN apt-get update && apt-get install -y zip && \
  10. mkdir /opt/protoc && cd /opt/protoc && wget https://github.com/protocolbuffers/protobuf/releases/download/v3.7.0/protoc-3.7.0-linux-x86_64.zip && \
  11. unzip protoc-3.7.0-linux-x86_64.zip
  12. # Copy the grpc proto file and generate the go module
  13. RUN /opt/protoc/bin/protoc --go_out=/app/proto --proto_path=/app/proto --go_opt=paths=source_relative --go-grpc_out=/app/proto --go-grpc_opt=paths=source_relative /app/proto/text.proto /app/proto/server.proto
  14. EXPOSE 5051
  15. RUN go build -o /server
  16. ENTRYPOINT ["/server"]

目录树

  1. 1.text
  2. ├── admin
  3. ├── Dockerfile
  4. ├── app.js
  5. ├── package.json
  6. └── web
  7. ├── html
  8. └── index.html
  9. └── resources
  10. ├── compose.yaml
  11. ├── db
  12. ├── Dockerfile
  13. ├── main.go
  14. ├── proto
  15. ├── db.pb.go
  16. ├── db.proto
  17. └── db_grpc.pb.go
  18. └── text.db
  19. ├── go.mod
  20. ├── go.sum
  21. ├── proto
  22. ├── text.pb.go
  23. └── text.proto
  24. └── server
  25. ├── Dockerfile
  26. ├── main.go
  27. ├── proto
  28. ├── server.pb.go
  29. ├── server.proto
  30. └── server_grpc.pb.go
  31. └── text
  32. ├── text.go
  33. └── text_test.go

我能够在根目录的text目录中运行以下protoc命令:

  1. protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/text.proto db/proto/db.proto server/proto/server.proto

并在本地运行服务器,但无法构建我的Docker镜像:

CMD

  1. docker build -f server/Dockerfile -t server .

错误

  1. => ERROR [7/8] RUN /opt/protoc/bin/protoc --go_out=/app/proto --proto_path=/app/proto --go_opt=paths=source_relative --go-grpc_out=/app/proto --go-grpc_opt=paths=source_relative 0.4s
  2. ------
  3. > [7/8] RUN /opt/protoc/bin/protoc --go_out=/app/proto --proto_path=/app/proto --go_opt=paths=source_relative --go-grpc_out=/app/proto --go-grpc_opt=paths=source_relative /app/proto/text.proto /app/proto/server.proto:
  4. #11 0.427 proto/text.proto: File not found.
  5. #11 0.429 server.proto: Import "proto/text.proto" was not found or had errors.
  6. #11 0.431 server.proto:25:5: "text.Status" seems to be defined in "text.proto", which is not imported by "server.proto". To use it here, please add the necessary import.
  7. ------
  8. executor failed running [/bin/sh -c /opt/protoc/bin/protoc --go_out=/app/pro
text/server/proto
  1. syntax="proto3";
  2. package server;
  3. import "proto/text.proto";
  4. option go_package = "github.com/amb1s1/text/server/proto/server";
  5. message SendMessageRequest {
  6. string token = 1;
  7. string phone = 2;
  8. string message = 3;
  9. bool dry_run = 4;
  10. };
  11. message SendMessageResponse {
  12. text.Status status = 1;
  13. };
  14. service Text {
  15. // SendMessage sents SMS message.
  16. rpc SendMessage(SendMessageRequest) returns (SendMessageResponse) {}
  17. }

text/proto/

  1. syntax="proto3";
  2. package text;
  3. option go_package = "github.com/amb1s1/text/proto";
  4. enum Status {
  5. UNKNOW = 0;
  6. OK = 1;
  7. TOKENS_EXISTS = 2;
  8. TOKEN_NOT_FOUND = 3;
  9. FAILED_NOT_SENT= 4;
  10. DRY_RUN_OK = 5;
  11. ZERO_BALANCE = 6;
  12. WRONG_TOKEN = 7;
  13. }
英文:

I'm running with an issue where I can't build Dockerfile that includes multiple proto files(server and text). The server proto is within the Dockerfile dir, but the text proto is within the Dockerfile parent. So I'm building the Dockerfile in the parent dir to COPY the text proto to the Docker build.

The Docker build complaining about proto/text.proto: File not found. even though I COPY the proto/text.proto to the exact location as server/proto/server.proto.

Here are all my files:

DockerFile

  1. FROM --platform=linux/x86_64 golang:1.19.3-bullseye
  2. # Install grpc
  3. RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 && \
  4. go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
  5. WORKDIR /app
  6. COPY server/. /app
  7. COPY proto/text.proto /app/proto/text.proto
  8. # Install protoc and zip system library
  9. RUN apt-get update && apt-get install -y zip && \
  10. mkdir /opt/protoc && cd /opt/protoc && wget https://github.com/protocolbuffers/protobuf/releases/download/v3.7.0/protoc-3.7.0-linux-x86_64.zip && \
  11. unzip protoc-3.7.0-linux-x86_64.zip
  12. # Copy the grpc proto file and generate the go module
  13. RUN /opt/protoc/bin/protoc --go_out=/app/proto --proto_path=/app/proto --go_opt=paths=source_relative --go-grpc_out=/app/proto --go-grpc_opt=paths=source_relative /app/proto/text.proto /app/proto/server.proto
  14. EXPOSE 5051
  15. RUN go build -o /server
  16. ENTRYPOINT ["/server"]

Dir Tree

  1. 1.text
  2. ├── admin
  3. │   ├── Dockerfile
  4. │   ├── app.js
  5. │   ├── package.json
  6. │   └── web
  7. │   ├── html
  8. │   │   └── index.html
  9. │   └── resources
  10. ├── compose.yaml
  11. ├── db
  12. │   ├── Dockerfile
  13. │   ├── main.go
  14. │   ├── proto
  15. │   │   ├── db.pb.go
  16. │   │   ├── db.proto
  17. │   │   └── db_grpc.pb.go
  18. │   └── text.db
  19. ├── go.mod
  20. ├── go.sum
  21. ├── proto
  22. │   ├── text.pb.go
  23. │   └── text.proto
  24. └── server
  25. ├── Dockerfile
  26. ├── main.go
  27. ├── proto
  28. │   ├── server.pb.go
  29. │   ├── server.proto
  30. │   └── server_grpc.pb.go
  31. └── text
  32. ├── text.go
  33. └── text_test.go

I'm able to run the following protoc in the root text dir:

  1. protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/text.proto db/proto/db.proto server/proto/server.proto

And run the server locally, but I'm not able to build my Docker:

CMD

  1. docker build -f server/Dockerfile -t server .
  1. => ERROR [7/8] RUN /opt/protoc/bin/protoc --go_out=/app/proto --proto_path=/app/proto --go_opt=paths=source_relative --go-grpc_out=/app/proto --go-grpc_opt=paths=source_relative 0.4s
  2. ------
  3. > [7/8] RUN /opt/protoc/bin/protoc --go_out=/app/proto --proto_path=/app/proto --go_opt=paths=source_relative --go-grpc_out=/app/proto --go-grpc_opt=paths=source_relative /app/proto/text.proto /app/proto/server.proto:
  4. #11 0.427 proto/text.proto: File not found.
  5. #11 0.429 server.proto: Import "proto/text.proto" was not found or had errors.
  6. #11 0.431 server.proto:25:5: "text.Status" seems to be defined in "text.proto", which is not imported by "server.proto". To use it here, please add the necessary import.
  7. ------
  8. executor failed running [/bin/sh -c /opt/protoc/bin/protoc --go_out=/app/pro
text/server/proto
  1. syntax="proto3";
  2. package server;
  3. import "proto/text.proto";
  4. option go_package = "github.com/amb1s1/text/server/proto/server";
  5. message SendMessageRequest {
  6. string token = 1;
  7. string phone = 2;
  8. string message = 3;
  9. bool dry_run = 4;
  10. };
  11. message SendMessageResponse {
  12. text.Status status = 1;
  13. };
  14. service Text {
  15. // SendMessage sents SMS message.
  16. rpc SendMessage(SendMessageRequest) returns (SendMessageResponse) {}
  17. }

text/proto/

  1. syntax="proto3";
  2. package text;
  3. option go_package = "github.com/amb1s1/text/proto";
  4. enum Status {
  5. UNKNOW = 0;
  6. OK = 1;
  7. TOKENS_EXISTS = 2;
  8. TOKEN_NOT_FOUND = 3;
  9. FAILED_NOT_SENT= 4;
  10. DRY_RUN_OK = 5;
  11. ZERO_BALANCE = 6;
  12. WRONG_TOKEN = 7;
  13. }

答案1

得分: 3

根据评论,您的Docker镜像中有以下目录结构:

  1. /app/proto/server.proto
  2. /app/proto/text.proto

server.proto 使用 import "proto/text.proto" 导入了 text.proto

这意味着 protoc 将在导入路径中查找名为 proto/text.proto 的文件。您在 protoc 的参数中指定了 --proto_path=/app/proto,这意味着 protoc 将检查 /app/proto/proto/text.proto,但该文件不存在(因此出现了问题)。要解决此问题,请删除 --proto_path=/app/proto(这样 protoc 将使用工作文件夹)或指定 --proto_path=/app

英文:

As per the comments; within your docker image you have the directory structure:

  1. /app/proto/server.proto
  2. /app/proto/text.proto

server.proto imports text.proto with import "proto/text.proto".

This means that protoc will be looking for a file called proto/text.proto within the import path. You specified --proto_path=/app/proto as an argument to protoc meaning that protoc will check for /app/proto/proto/text.proto which does not exist (hence the issue). To fix this remove the --proto_path=/app/proto (so protoc uses the working folder) or specify --proto_path=/app.

huangapple
  • 本文由 发表于 2022年11月13日 00:29:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/74414655.html
匿名

发表评论

匿名网友
#

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定