Как скачать все зависимости с vgo и заданным go.mod?
Я работаю над проектом go, используя vgo, с Dockerfile, и я бы хотел, чтобы docker кэшировал зависимости проекта так, чтобы он имел два свойства:
- Если
go.mod
изменения файла, зависимости будут повторно загружены - Если я изменю файл в пакете, но не изменю
go.mod
, зависимости не будут повторно загружены.
Прямо сейчас я делаю:
...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...
Но если вы измените файл go, файл dockerfile нужно будет восстановить из COPY
слой вперед.
Короче говоря, я хотел бы сделать:
...
RUN go get -u golang.org/x/vgo
COPY go.mod /go/src/whatever
RUN vgo install_dependencies
COPY . /go/src/whatever
RUN vgo install
...
Таким образом, если я изменю go.mod
все зависимости будут загружены и перестроены, но в противном случае мы можем перейти прямо к созданию двоичного файла.
Я вижу несколько способов получить подобное поведение, но все они имеют недостатки:
- Я мог бы скопировать
$GOPATH/src/mod
в контейнер докера, но там будет много файлов, которые мне не нужны - Я мог бы
vgo mod -vendor
прежде чем я соберу докер-контейнер и скопирую каталог vendor, но разработчик должен помнить, что нужно запуститьvgo mod -vendor
каждый раз, когдаgo.mod
изменения, иначе приложение не будет собираться, и им придется работатьvgo mod -vendor
перед повторной попыткой сборки докера.
Можете ли вы придумать способ для меня, чтобы получить поведение, как мой воображаемый vgo install_dependencies
? Я пропускаю трюк VGO, чтобы сделать это?
2 ответа
tl;dr: в текущем go master и в будущих go релизах, go mod download
сделаю эту работу. А пока тебе нужен взлом.
Из-за слабости сусликов я был отослан к этой проблеме: https://github.com/golang/go/issues/26610 где я узнал, что это будет делать более или менее то, что я хочу (при условии, что вы используете версию Go 1.11beta3):
# Populate the module cache based on the go.{mod,sum} files.
COPY go.mod .
COPY go.sum .
RUN go list -e $(go list -f '{{.Path}}' -m all)
Позже в теме, Русс Кокс реализует go mod download
, который будет доступен в следующем выпуске go
, позволяя мне убрать глупых go list
взломать выше.
У меня была точно такая же проблема, я хотел сделать кеширование Docker более точным.
Поэтому я только что написал свой собственный инструмент для этого: https://github.com/gladkikhartem/gomodget
Теперь мой конвейер Docker-in-Docker занимает всего 10 секунд, и журнал сборки Docker выглядит так:
Step 4/15 : RUN go get -u golang.org/x/vgo
---> Using cache
---> 12c672a07a16
Step 5/15 : RUN go get github.com/gladkikhartem/gomodget
---> Using cache
---> acc70fea0edc
Step 7/15 : COPY go.mod .
---> Using cache
---> 41bae1ca7428
Step 8/15 : RUN gomodget
---> Using cache
---> 758100f7dde2
Step 9/15 : COPY . .
---> cc833c5bc810
Step 10/15 : RUN vgo build -ldflags '-extldflags "-static"' -o /bin/app