如何在Go Docker多阶段构建中添加本地依赖项?

时间:2018-05-16 11:03:50

标签: docker go dockerfile

如何在同一个Go项目中的文件夹中添加本地依赖项?

我有以下目录结构:

.
├── backend
│   ├── Dockerfile
│   ├── conduit
│   │   └── get_data.go
│   ├── main.go
│   ├── main_test.go
│   ├── storage
│   │   ├── create_client.go
│   │   └── read_data.go
├── cron_job
│   ├── Dockerfile
│   ├── main.go
│   └── main_test.go

和Dockerfile:

FROM golang:1.10.1 as builder
ADD . github.com/dalderman77/phacts/backend/conduit
ADD . github.com/dalderman77/phacts/backend/storage
WORKDIR /go/src/github.com/dalderman77/phacts/cron_job
# Get dependencies
RUN go get -d -v cloud.google.com/go/datastore golang.org/x/net/context
COPY . .
# Compile Go binary
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

# Create smaller lightweight container
FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# Copy binary from previous stage
COPY --from=builder /go/src/github.com/dalderman77/phacts/cron_job/main .
CMD ["./main"]  

到目前为止我所基于的是Use multi-stage builds

问题是编译的二进制文件依赖于后端目录中的代码。它在本地编译很好,但我不确定如何正确添加这些依赖项,以便它们可以在容器中编译:

main.go:9:2: cannot find package "github.com/dalderman77/phacts/backend/conduit" in any of:
        /usr/local/go/src/github.com/dalderman77/phacts/backend/conduit (from $GOROOT)
        /go/src/github.com/dalderman77/phacts/backend/conduit (from $GOPATH)
main.go:10:2: cannot find package "github.com/dalderman77/phacts/backend/storage" in any of:
        /usr/local/go/src/github.com/dalderman77/phacts/backend/storage 

1 个答案:

答案 0 :(得分:2)

在Dockerfile中,此命令用于编译代码:

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

这将生成你的二进制static,允许你执行构建的第二步,因为你现在可以从小图像开始(在你的情况下是高山,但你甚至可以尝试使用empty image)不依赖于容器内的任何依赖。

在您的示例中,您将ca-certificates添加到最终图像中:

RUN apk --no-cache add ca-certificates

如果您在应用程序中发出HTTPS请求,则可能需要这样做,因为alpine容器在其文件系统中没有任何证书。通常,您的应用程序所需的任何静态资产(例如图像,html /电子邮件模板,脚本等)都必须通过COPY或ADD命令添加到生成的图像中。

另请参阅this outstanding guide了解如何构建最小的docker容器。

修改:您的构建问题发生是因为cron_job无法找到来自backend的软件包,因为您没有将backend复制到容器中在正确的$ GOPATH文件夹中。要解决此问题,您需要使用依赖项管理器工具来提供依赖项。目前的正式版是dep

恢复cron_job的依赖关系(在您的计算机上本地,容器内的 NOT )将创建vendor子文件夹,其中将存储项目的每个所需依赖项。现在,当您将cron_job复制到容器时,构建还将查看vendor文件夹以检查缺少的依赖项。