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)
Подводя итог, мой текущий процесс сборки выглядит следующим образом:
- Редактировать код
- Создайте каждый исполняемый файл Go, используя
go build
, Исполняемый файл называетсяmain
и сохраняется вprogramX/main/
каталог, рядомmain.go
, - Зафиксируйте и нажмите код (так как
main
исполняемые файлы отслеживаются Git) в моей главной ветке. - Build Trigger создает четыре образа Docker, используя
main
файл построен в шаге 1.
Цель
Я хотел бы исключить Шаг 1 из моего процесса сборки, чтобы мне больше не нужно было компилировать свои исполняемые файлы локально и не нужно отслеживать мои main
исполняемые файлы в Git.
В общем, вот мой идеальный процесс:
- Редактировать код, совершать, нажимать на пульт.
- Build Trigger компилирует все четыре программы, строит все четыре изображения.
- Расслабьтесь:)
Попытка решения
Я использовал шаг сборки с открытым исходным кодом 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)
Это даже не ищет каталог продавца?
Что дальше?
Я предполагаю, что одно из следующего верно:
- Я не уточняю
GOPATH
/PROJECT_ROOT
правильно в файле запроса сборки. Но если это так, какова правильная настройка? - Мой проект не структурирован правильно.
- То, что я пытаюсь сделать, невозможно:(*
- Мне нужно как-то сделать пользовательский шаг сборки.
- Используемая версия Go старая, но как я могу это проверить?
Я не могу найти в Интернете примеров того, чего я пытаюсь достичь, и я нахожу документацию GCP по этому вопросу совершенно отсутствующей.
Любая помощь будет принята с благодарностью!
2 ответа
Исправлена проблема (но не совсем точно как...), благодаря этим изменениям:
- Задавать
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) - Удалить
dirs
поле для шага сборки Go - Установить
-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
,