-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/go: precompile dependencies for docker image cache #45474
Comments
Without the source code to list your actual dependencies (as opposed to everything that's possibly reachable from the module graph, including test dependencies of you dependencies etc...), you're going to massively overbuild. I think the closest you can do today might be the following, with the caveats that each module is built independently so shared dependencies at different versions will be built multiple times, and it also includes trimmed out dependencies. for p in $(go list -m -f '{{ if not .Main }}{{ .Path }}/...@{{ .Version }}{{ end}}' all) ; do
go install $p
done You may have better luck using docker buildx to mount a cache in (caveat moby/buildkit#1512) #syntax=docker/dockerfile:1.2
FROM golang:alpine AS build
WORKDIR /workspace
COPY . .
RUN --mount=type=cache,id=gomod,target=/go/pkg/mod \
--mount=type=cache,id=gobuild,target=/root/.cache/go-build \
go build -o app . |
I don't think any new feature in the I'm marking this as a documentation issue though since we could really use a guide on efficiently building container images. |
Had never heard of docker buildx. Unfortunately our CI uses kaniko and it doesn't support those extra flags ;-; GoogleContainerTools/kaniko#969. |
You could try a different approach with kaniko: specify a directory under |
@jayconrod I'd like the ability to create the list of modules on demand instead of a manual maintenance task. Seems there are at least some caveats with
Would |
@andig There's no way for the For |
I believe that this is the same issue as #27719, which is still not solved. |
A command to do that would be a perfectly fine compromise to me, way better than the current situation anyway. The dependencies rarely changes or needs to be rebuilt (at most a few times per month anyway), while the actual source code of the application needs to be rebuilt multiple times per minute when developing. |
This issue may reveal some fundamental misunderstanding I have about golang/compilers, but here goes:
Some of the dependencies for a monolithic golang program on our backend are quite large. Several of them use code generation as a generics workaround and are large enough to force us to use internal gitlab runners because of OOM errors. Currently we use
go mod download
as a build step in containerizing it, so that downloading those dependencies is cached. However, as far as I can tell, there's no way to run the equivalent ofgo get
for just a go.mod and go.sum file; we can download, but not compile these dependencies that mostly stay the same from build to build.This means that every time we build our backend golang program we have to recompile all of the libraries that that program uses from scratch, instead of caching that as a build step and only recompiling when we change our go.mod/go.sum files.
I'd like a go command (if it doesn't exist already, and doesn't admit some fundamental misunderstanding of how libraries get compiled) to get much of this work done before we
COPY
our source code into the docker image. Maybe this would just be a modification of go get that ignored the fact that there was no source code in the working directory when a go.mod file exists specifying all of the libraries used for a package. Such a command would shave a lot of build time in our CI.The text was updated successfully, but these errors were encountered: