英文:
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
FROM --platform=linux/x86_64 golang:1.19.3-bullseye
# Install grpc
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 && \
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
WORKDIR /app
COPY server/. /app
COPY proto/text.proto /app/proto/text.proto
# Install protoc and zip system library
RUN apt-get update && apt-get install -y zip && \
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 && \
unzip protoc-3.7.0-linux-x86_64.zip
# Copy the grpc proto file and generate the go module
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
EXPOSE 5051
RUN go build -o /server
ENTRYPOINT ["/server"]
目录树
1.text
├── admin
│ ├── Dockerfile
│ ├── app.js
│ ├── package.json
│ └── web
│ ├── html
│ │ └── index.html
│ └── resources
├── compose.yaml
├── db
│ ├── Dockerfile
│ ├── main.go
│ ├── proto
│ │ ├── db.pb.go
│ │ ├── db.proto
│ │ └── db_grpc.pb.go
│ └── text.db
├── go.mod
├── go.sum
├── proto
│ ├── text.pb.go
│ └── text.proto
└── server
├── Dockerfile
├── main.go
├── proto
│ ├── server.pb.go
│ ├── server.proto
│ └── server_grpc.pb.go
└── text
├── text.go
└── text_test.go
我能够在根目录的text
目录中运行以下protoc命令:
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
docker build -f server/Dockerfile -t server .
错误
=> 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
------
> [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:
#11 0.427 proto/text.proto: File not found.
#11 0.429 server.proto: Import "proto/text.proto" was not found or had errors.
#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.
------
executor failed running [/bin/sh -c /opt/protoc/bin/protoc --go_out=/app/pro
text/server/proto
syntax="proto3";
package server;
import "proto/text.proto";
option go_package = "github.com/amb1s1/text/server/proto/server";
message SendMessageRequest {
string token = 1;
string phone = 2;
string message = 3;
bool dry_run = 4;
};
message SendMessageResponse {
text.Status status = 1;
};
service Text {
// SendMessage sents SMS message.
rpc SendMessage(SendMessageRequest) returns (SendMessageResponse) {}
}
text/proto/
syntax="proto3";
package text;
option go_package = "github.com/amb1s1/text/proto";
enum Status {
UNKNOW = 0;
OK = 1;
TOKENS_EXISTS = 2;
TOKEN_NOT_FOUND = 3;
FAILED_NOT_SENT= 4;
DRY_RUN_OK = 5;
ZERO_BALANCE = 6;
WRONG_TOKEN = 7;
}
英文:
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
FROM --platform=linux/x86_64 golang:1.19.3-bullseye
# Install grpc
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 && \
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
WORKDIR /app
COPY server/. /app
COPY proto/text.proto /app/proto/text.proto
# Install protoc and zip system library
RUN apt-get update && apt-get install -y zip && \
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 && \
unzip protoc-3.7.0-linux-x86_64.zip
# Copy the grpc proto file and generate the go module
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
EXPOSE 5051
RUN go build -o /server
ENTRYPOINT ["/server"]
Dir Tree
1.text
├── admin
│   ├── Dockerfile
│   ├── app.js
│   ├── package.json
│   └── web
│   ├── html
│   │   └── index.html
│   └── resources
├── compose.yaml
├── db
│   ├── Dockerfile
│   ├── main.go
│   ├── proto
│   │   ├── db.pb.go
│   │   ├── db.proto
│   │   └── db_grpc.pb.go
│   └── text.db
├── go.mod
├── go.sum
├── proto
│   ├── text.pb.go
│   └── text.proto
└── server
├── Dockerfile
├── main.go
├── proto
│   ├── server.pb.go
│   ├── server.proto
│   └── server_grpc.pb.go
└── text
├── text.go
└── text_test.go
I'm able to run the following protoc in the root text
dir:
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
docker build -f server/Dockerfile -t server .
Error
=> 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
------
> [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:
#11 0.427 proto/text.proto: File not found.
#11 0.429 server.proto: Import "proto/text.proto" was not found or had errors.
#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.
------
executor failed running [/bin/sh -c /opt/protoc/bin/protoc --go_out=/app/pro
text/server/proto
syntax="proto3";
package server;
import "proto/text.proto";
option go_package = "github.com/amb1s1/text/server/proto/server";
message SendMessageRequest {
string token = 1;
string phone = 2;
string message = 3;
bool dry_run = 4;
};
message SendMessageResponse {
text.Status status = 1;
};
service Text {
// SendMessage sents SMS message.
rpc SendMessage(SendMessageRequest) returns (SendMessageResponse) {}
}
text/proto/
syntax="proto3";
package text;
option go_package = "github.com/amb1s1/text/proto";
enum Status {
UNKNOW = 0;
OK = 1;
TOKENS_EXISTS = 2;
TOKEN_NOT_FOUND = 3;
FAILED_NOT_SENT= 4;
DRY_RUN_OK = 5;
ZERO_BALANCE = 6;
WRONG_TOKEN = 7;
}
答案1
得分: 3
根据评论,您的Docker镜像中有以下目录结构:
/app/proto/server.proto
/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:
/app/proto/server.proto
/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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论