我有以下代码结构,我正在尝试构建我的 Dockerfile 以最大化缓存等。
serverfoo/
Dockerfile
main.go
serverbar/
Dockerfile
main.go
proto/
Dockerfile
sharedproto.proto // Generates a sharedproto.pb.go file to be imported.
两个
serverfoo
和 serverbar
导入编译好的sharedproto.pb.go
我在工作站上手动重新生成的文件。这工作正常,但现在我正在尝试将我的两台服务器容器化。我的服务器文件夹的 Dockerfiles 不能(默认)复制
proto/
内容。理想情况下,我将 protobuf 预编译为 sharedproto.pb.go
然后将该文件的缓存版本导入两个服务器 Dockerfile。目标是缓存已编译的 protobuf,直到底层 proto 被修改。我是 Docker 新手,需要一些此类事情的最佳实践。我想避免根
Dockerfile
在我的项目目录中,它只有代码来编译无数不同的服务器。我愿意在某种程度上重组我的项目。
最佳答案
NOTE: I suppose your target is to have on the specific server container both the compiled go file ( from specific main.go file ) and the compiled protocol buffer file ( from shared sharedproto.proto file ).
假设您的文件在您的工作站上按如下方式组织:
serverfoo/
Dockerfile
main.go
serverbar/
Dockerfile
main.go
proto/
Dockerfile
sharedproto.proto
您可以使用多阶段构建来构建特定的服务器 Dockerfile,如下所示(例如 serverbar Dockerfile ):
#####
# The serverbar Dockerfile
#####
#----
# Compile proto stage
#----
FROM moul/protoc-gen-gotemplate AS protostage
WORKDIR /workspace
# Copy .proto file
COPY proto/sharedproto.proto .
# Compile .pb.go
RUN protoc -I=. --go_out=. sharedproto.proto
#----
# Build stage
#----
FROM golang:1.12.4-alpine3.9 as buildstage
WORKDIR /workspace
COPY serverbar/main.go .
RUN GOOS=linux GOARCH=amd64 go build -o serverbar main.go
#----
# Final stage
#----
FROM alpine:3.7
WORKDIR /home
COPY --from=buildstage workspace/serverbar .
COPY --from=protostage workspace/sharedproto.pb.go .
CMD ["./serverbar"]
使用这种方法,您基本上有以下 3 个阶段:
具体来说,遵循 Dockerfile 指令会生成 工作区/sharedproto.pb.go :
RUN protoc -I=. --go_out=. sharedproto.proto
具体来说,遵循 Dockerfile 指令会生成 工作区/服务器栏 可执行:
RUN GOOS=linux GOARCH=amd64 go build -o serverbar main.go
COPY --from=buildstage workspace/serverbar .
COPY --from=protostage workspace/sharedproto.pb.go .
此解决方案的优点之一是,对于每个服务器构建,您可以缓存已编译的 protobuf,直到修改底层 proto。
示例:
第一次 build 服务器栏 container 我们可以注意到 .proto 编译是在一个 ID 为 的新容器上执行的。 92ae211bd27d :
> docker build -f serverbar/Dockerfile .
Sending build context to Docker daemon 10.24kB
Step 1/13 : FROM moul/protoc-gen-gotemplate AS protostage
---> 635345fde953
Step 2/13 : WORKDIR /workspace
---> Using cache
---> de8890a5e775
Step 3/13 : COPY proto/sharedproto.proto .
---> 1253fa0576aa
Step 4/13 : RUN protoc -I=. --go_out=. sharedproto.proto
---> Running in 8426f5810b98
Removing intermediate container 8426f5810b98
---> 92ae211bd27d <=========================================
Step 5/13 : FROM golang:1.12.4-alpine3.9 as buildstage
---> b97a72b8e97d
Step 6/13 : WORKDIR /workspace
....
然后在不修改 sharedproto.proto 的情况下再次构建,我们可以注意到 ID 为 的容器92ae211bd27d 从缓存中重复使用。
> docker build -f serverbar/Dockerfile .
Sending build context to Docker daemon 10.24kB
Step 1/13 : FROM moul/protoc-gen-gotemplate AS protostage
---> 635345fde953
Step 2/13 : WORKDIR /workspace
---> Using cache
---> de8890a5e775
Step 3/13 : COPY proto/sharedproto.proto .
---> Using cache
---> 1253fa0576aa
Step 4/13 : RUN protoc -I=. --go_out=. sharedproto.proto
---> Using cache <=========================================
---> 92ae211bd27d
Step 5/13 : FROM golang:1.12.4-alpine3.9 as buildstage
---> b97a72b8e97d
....
关于docker - 多个 Dockerfile 在项目中重用共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59819333/