Google Cloud Container Builder - сборка контейнера Docker из исходного кода Go с зависимостями от производителя

Фон

Связанный вопрос: Google Container Builder: Как установить зависимости govendor на этапе сборки?

Я пытаюсь использовать Google Cloud Container Builder для автоматизации создания моих Docker-контейнеров с помощью триггеров сборки.

Мой код в Go, и у меня есть vendor папка (зарегестрированная в Git) в корне моего проекта, которая содержит все мои зависимости Go.

Мой проект имеет четыре бинарных файла, которые нужно докеризовать, структурированные следующим образом:

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, используя go build, Исполняемый файл называется main и сохраняется в programX/main/ каталог, рядом main.go,
  3. Зафиксируйте и нажмите код (так как main исполняемые файлы отслеживаются Git) в моей главной ветке.
  4. Build Trigger создает четыре образа Docker, используя main файл построен в шаге 1.

Цель

Я хотел бы исключить Шаг 1 из моего процесса сборки, чтобы мне больше не нужно было компилировать свои исполняемые файлы локально и не нужно отслеживать мои main исполняемые файлы в Git.

В общем, вот мой идеальный процесс:

  1. Редактировать код, совершать, нажимать на пульт.
  2. Build Trigger компилирует все четыре программы, строит все четыре изображения.
  3. Расслабьтесь:)

Попытка решения

Я использовал шаг сборки с открытым исходным кодом Go следующим образом:

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)

После попытки различных комбинаций установки PROJECT_ROOT и GOPATH в env поле build-programX Я продолжал получать ту же ошибку для каждого пакета, используемого в моем проекте (путь к файлу варьируется):

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)

Это даже не ищет каталог продавца?

Что дальше?

Я предполагаю, что одно из следующего верно:

  1. Я не уточняю GOPATH / PROJECT_ROOT правильно в файле запроса сборки. Но если это так, какова правильная настройка?
  2. Мой проект не структурирован правильно.
  3. То, что я пытаюсь сделать, невозможно:(*
  4. Мне нужно как-то сделать пользовательский шаг сборки.
  5. Используемая версия Go старая, но как я могу это проверить?

Я не могу найти в Интернете примеров того, чего я пытаюсь достичь, и я нахожу документацию GCP по этому вопросу совершенно отсутствующей.

Любая помощь будет принята с благодарностью!

2 ответа

Решение

Исправлена ​​проблема (но не совсем точно как...), благодаря этим изменениям:

  1. Задавать PROJECT_ROOT в my_rootтак, что код, который я хочу скомпилировать, находится в my_root/program1/main/main.go (спасибо Джону Асмуту за ответ: /questions/7639664/google-cloud-container-builder-sborka-kontejnera-docker-iz-ishodnogo-koda-go-s-zavisimostyami-ot-proizvoditelya/7639681#7639681)
  2. Удалить dirs поле для шага сборки Go
  3. Установить -o флаг для ./program1/main/mainи окончательная сборка ./program1/main/main.go

Ранее я был cdвходя в program1/main каталог на этапе сборки, и по какой-то причине go build искал пакеты внутри my_root/program1/main вместо my_root, Weird!

Проблема с #1: PROJECT_ROOT ссылается на желаемый путь импорта ваших двоичных файлов. Например, если в program1/main/main.go вы импортируете "github.com/foo/bar/program1" чтобы получить пакет, определенный в program1/program1.goВы бы установили PROJECT_ROOT=github.com/foo/bar,