Ускорение Go строит с помощью кеша 1.10 build в контейнерах Docker

У меня есть проект Go с большим vendor/ каталогом, который почти никогда не изменяется.

Я пытаюсь использовать новую функцию кеширования1.10 для ускорения сборки в локальном режиме Docker.

Избежать перекомпиляции моего vendor/ каталога было бы достаточно оптимизировать. Поэтому я пытаюсь сделать Go эквивалентом этого общего шаблона Dockerfile для Python:

FROM python
COPY requirements.txt . # <-- copy your dependency list
RUN pip install -r requirements.txt # <-- install dependencies
COPY ./src ... # <-- your actual code (everything above is cached)

Аналогичным образом я попытался:

FROM golang:1.10-alpine
COPY ./vendor ./src/myproject/vendor
RUN go build -v myproject/vendor/... # <-- pre-build & cache "vendor/"
COPY . ./src/myproject

Однако это дает ошибку "не удается найти пакет" (вероятно, из-за того, что вы также не можете создавать вещи в поставщике или напрямую).

Кто-нибудь мог это понять?

2 ответа

Просто используйте go install -i./vendor/...

Рассмотрим следующий файл Docker:

FROM golang:1.10-alpine

ARG APP
ENV PTH $GOPATH/src/$APP
WORKDIR $PTH

# Pre-compile vendors.
COPY vendor/ $PTH/vendor/
RUN go install -i ./vendor/...

ADD . $PTH/

# Display time taken and the list of the packages being compiled.
RUN time go build -v

Вы можете проверить, как он делает что-то вроде:

docker build -t test --build-arg APP=$(go list .) .

В проекте, над которым я работаю, без предварительной компиляции, требуется ~ 12 секунд с пакетом 90+ каждый раз, после чего он принимает ~ 1.2 с только 3 (только локальные).

Если у вас все еще есть "невозможно найти пакет", это означает, что отсутствуют поставщики. Повторный запуск dep ensure его исправление.

Другой совет, не связанный с Go, заключается в том, чтобы ваш .dockerignore начинался с *. т.е. игнорировать все, а затем присваивать белый список тем, что вам нужно.


Здесь что-то, что работает для меня:

FROM golang:1.10-alpine
WORKDIR /usr/local/go/src/github.com/myorg/myproject/
COPY vendor vendor
RUN find vendor -maxdepth 2 -mindepth 2 -type d -exec sh -c 'go install -i github.com/myorg/myproject/{}/... || true' \;
COPY main.go .
RUN go build main.go

Он гарантирует, что сначала будут установлены вендорные библиотеки. Пока вы не меняете библиотеку, вы в порядке.

licensed under cc by-sa 3.0 with attribution.