Google Cloud Container Builder - 使用 vendor 的依赖项从 Go 源代码构建 Docker 容器

标签 go google-cloud-platform google-container-registry govendor google-container-builder

背景

相关问题:Google Container Builder: How to install govendor dependencies during build step?

我正在尝试使用 Google Cloud Container Builder 通过构建触发器自动构建我的 Docker 容器。

我的代码位于 Go 中,并且我的项目根目录中有一个 vendor 文件夹(已 checkin 到 Git),其中包含我的所有 Go 依赖项。

我的项目有四个需要 Docker 化的二进制文件,结构如下:

vendor/
   ...
program1/
    program1.go
    main/
        main.go
        Dockerfile
program2/
    program2.go
    main/
        main.go
        Dockerfile
...

每个程序的 Dockerfile 都很简单:

FROM alpine
ADD main main
ENTRYPOINT ["/main"]

我设置了一个构建触发器来跟踪我的 master 分支。触发器运行以下构建请求 (cloudbuild.yaml),该请求利用开源 Docker 构建步骤:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/program1:0.1.15-$SHORT_SHA', '.']
  dir: 'program1/main'

  ... (repeated for each program)
  (images, tags omitted)

总而言之,我当前的构建过程如下:

  1. 编辑代码。
  2. 使用 go build 构建每个 Go 可执行文件。该可执行文件名为 main,并与 main.go 一起保存在 programX/main/ 目录中。
  3. 提交代码并将其推送到我的主分支(因为 main 可执行文件由 Git 跟踪)。
  4. Build Trigger 使用第 1 步中构建的 main 文件创建四个 Docker 镜像。

目标

我想从我的构建过程中消除第 1 步,这样我就不再需要在本地编译我的可执行文件,也不需要在 Git 中跟踪我的 main 可执行文件。

总而言之,这是我理想的流程:

  1. 编辑代码、提交、推送到远程。
  2. 构建触发器编译所有四个程序,构建所有四个镜像。
  3. 放松:)

尝试的解决方案

我用的是开源的Go build step ,如下:

cloudbuild.yaml:(已更新)

steps:
- id: 'build-program1'
  name: 'gcr.io/cloud-builders/go'
  args: ['build', '-a', '-installsuffix', 'cgo', '-ldflags', '''-w''', '-o', 'main', './main.go']
  env: ['PROJECT_ROOT=/workspace', 'CGO_ENABLED=0', 'GOOS=linux']
  dir: 'program1/main'
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/program1:0.1.15-$SHORT_SHA', '.']
  dir: 'program1/main'
  waitFor: ['build-program1']

  ... (repeated for each program)
  (images, tags omitted)

build-programXenv 字段中尝试设置 PROJECT_ROOT 和 GOPATH 的各种组合后,我的项目中使用的每个包都不断收到相同的错误(文件路径各不相同):

cannot find package "github.com/acoshift/go-firebase-admin" in any of
Step #0 - "build-program1": /usr/local/go/src/github.com/acoshift/go-firebase-admin (from $GOROOT) 
Step #0 - "build-program1": /workspace/auth/main/gopath/src/github.com/acoshift/go-firebase-admin (from $GOPATH)

它甚至没有寻找 vendor 目录?

下一步做什么?

我的猜测是以下其中一项是正确的:

  1. 我没有在构建请求文件中正确指定 GOPATH/PROJECT_ROOT。但如果是这样,正确的设置是什么?
  2. 我的项目结构不正确。
  3. 我想做的事是不可能的:(*
  4. 我需要以某种方式进行自定义构建步骤。
  5. 使用的 Go 版本较旧 - 但我如何检查这一点?

我在网上找不到任何关于我想要实现的目标的示例,并且我发现 GCP 关于此主题的文档非常缺乏。

任何帮助将不胜感激!

最佳答案

问题在于#1:PROJECT_ROOT 指的是二进制文件所需的导入路径。例如,如果在 program1/main/main.go 中导入 "github.com/foo/bar/program1" 来获取 program1/中定义的包program1.go,您需要设置 PROJECT_ROOT=github.com/foo/bar

关于Google Cloud Container Builder - 使用 vendor 的依赖项从 Go 源代码构建 Docker 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46526250/

相关文章:

google-app-engine - 使用 gcloud app deploy 部署 GAE Flex 时出错

docker - 从 GCR (Google Container Registry) 导出 Docker 镜像

go - 这是在 Linux 上以 root 身份运行部分 go 代码的合理方法吗?

google-app-engine - 如何在 Google Cloud Platform 上安排 Cron 作业?

ssl - GCP Dataproc - 无法构建 kafka 消费者,无法加载 JKS 类型的 SSL keystore dataproc.jks

google-cloud-platform - Google Cloud Run/挂载 Google Storage Bucket

go - []byte 到 []int 或 []bool

google-app-engine - 来自 Intuit IPP 的请求 token 请求被拒绝

go - 发送 ISO8583 消息 Golang

google-cloud-platform - 用于插入特定 BigQuery 数据集的 IAM 自定义角色