Google Cloud容器生成器 - 使用销售依赖项构建来自Go源的Docker容器

时间:2017-10-02 13:15:52

标签: 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文件夹(签入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,并保存在programX/main/目录中,与main.go一起保存。
  3. 提交并推送代码(因为Git会跟踪main可执行文件)到我的主分支。
  4. 构建触发器使用步骤1中构建的main文件生成四个Docker镜像。
  5. 目标

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

    总之,这是我理想的过程:

    1. 编辑代码,提交,推送到远程。
    2. 构建触发器编译所有四个程序,构建所有四个图像。
    3. 放松:)
    4. 尝试解决方案

      我使用了开源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)
      

      env的{​​{1}}字段中尝试设置PROJECT_ROOT和GOPATH的各种组合后,我的项目中使用的每个包都会出现相同的错误(文件路径不同):

      build-programX

      它甚至没有找到供应商目录?

      下一步是什么?

      我的猜测是以下之一是真的:

      1. 我没有在构建请求文件中正确指定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) / GOPATH。但如果是这样,那么正确的设置是什么?
      2. 我的项目结构不正确。
      3. 我想做的事情是不可能的:(*
      4. 我需要以某种方式制作自定义构建步骤。
      5. Go使用的版本很旧 - 但我该如何查看?
      6. 我在网上找不到我想要实现的内容的例子,我发现GCP关于这个主题的文档非常缺乏。

        非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

修复了问题(但不确定如何......),这要归功于这些变化:

  1. PROJECT_ROOT设置为my_root,以便我要编译的代码位于my_root/program1/main/main.go(感谢John Asmuth的回答:https://stackoverflow.com/a/46526875/6905609
  2. 删除Go构建步骤的dirs字段
  3. -o标记设置为./program1/main/main,将最终版本设置为./program1/main/main.go
  4. 之前我在构建步骤中cd进入program1/main目录,由于某种原因,go build正在寻找my_root/program1/main而非my_root内的包}。怪异!