I'm working on a go project, using vgo, with a Dockerfile, and I'd like docker to cache the dependencies of the project such that it has two properties:
- If the
go.mod
file changes, the dependencies will be re-downloaded - If I change a file in the package, but do not change
go.mod
, the dependencies will not be re-downloaded.
Right now, I do:
...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...
But if you change a go file, the dockerfile will have to be rebuilt from the COPY
layer onwards.
What I'd like, in short, is to do:
...
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
...
That way, if I change go.mod
, all the dependencies will be downloaded and rebuilt, but otherwise, we can proceed right to building the binary.
I can see a couple of ways to get behavior like this, but all of them have drawbacks:
- I could copy
$GOPATH/src/mod
into the docker container, but that's going to have lots of files I don't need - I could
vgo mod -vendor
before I build the docker container, and copy the vendor directory, but that relies on the developer to remember to runvgo mod -vendor
every time thatgo.mod
changes, otherwise the app won't build and they'll have to runvgo mod -vendor
before retrying the docker build.
Can you think of a way for me to get behavior like my imaginary vgo install_dependencies
? Am I missing a vgo trick to do so?
tl;dr: In current go master and in future go releases,
go mod download
will do this job. For now you need a hack.On the gophers slack, I was referred to this issue: https://github.com/golang/go/issues/26610 where I learned that this would do more or less what I want (assuming here that you're using go version 1.11beta3):
Later in the thread, Russ Cox implements
go mod download
, which will be available in the next release ofgo
, allowing me to remove the sillygo list
hack above.update:
go mod download
is now widely available and you should use it on go 1.12 and later