Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build go dependencies in separate Docker layer

I'm trying to speed up Docker builds of my Go app. Right now, it's spending maybe 60s just building dependencies (it's a k8s controller, so there are a lot).

One very important constraint: my project depends on private GitHub repos. I do go mod vendor outside docker build, where I have creds for the repos set up.

My Dockerfile right now is roughly:

FROM golang:1.12

WORKDIR /src

COPY . .
RUN go build -mod=vendor
...

Even without having to download the deps, that build takes a while because it rebuilds several hundred packages every docker build.

What I'd like to do is something like:

FROM golang:1.12

WORKDIR /src

# these shouldn't change very often
COPY go.mod go.sum vendor ./
RUN go build -mod=vendor <all dependency packages>

COPY . .
RUN go build -mod=vendor
...

I tried parsing go.mod, but of course that lists modules, not packages. I tried go list but never managed to get a working incantation.

like image 670
nfirvine Avatar asked Mar 27 '19 19:03

nfirvine


1 Answers

I've got a nasty hack that seems to work:

FROM golang:1.12

WORKDIR /src

COPY go.mod go.sum ./
COPY vendor/ ./vendor
RUN go build -mod=vendor $(cat deps|grep -v mypackage | grep -v internal)

COPY . .
RUN go build -mod=vendor
...
go list -f '{{join .Deps "\n"}}'  > deps
docker build .
like image 127
nfirvine Avatar answered Nov 03 '22 06:11

nfirvine