简体   繁体   中英

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.

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 .

Docker documentation has a guide specific to Go docker images ( Build your Go image ).

It works as follows:

# Layer for dependency installation
COPY go.mod go.sum ./
RUN go mod download
# Layer for app build
COPY . .
RUN go build -o main .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM