Как скачать все зависимости с vgo и заданным go.mod?

Я работаю над проектом go, используя vgo, с Dockerfile, и я бы хотел, чтобы docker кэшировал зависимости проекта так, чтобы он имел два свойства:

  1. Если go.mod изменения файла, зависимости будут повторно загружены
  2. Если я изменю файл в пакете, но не изменю 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все зависимости будут загружены и перестроены, но в противном случае мы можем перейти прямо к созданию двоичного файла.

Я вижу несколько способов получить подобное поведение, но все они имеют недостатки:

  1. Я мог бы скопировать $GOPATH/src/mod в контейнер докера, но там будет много файлов, которые мне не нужны
  2. Я мог бы 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 
Другие вопросы по тегам