In short, my current use-case involves dynamically creating a Golang plugin inside a Docker container. The compilation involves some new input from the user (which is why it is not compiled beforehand), but the dependencies are static, and won't change.
Currently, the full compilation is done from scratch inside the Docker container (though go mod download
is used to reduce the time by a bit). I noticed that the go build
command ends up compiling a lot of the dependencies, which adds a non-trivial amount of time for the plugin compilation, which affects the usability of my application.
Is there a Go supported method or command to read through the go.mod
file and populate the GOCACHE
directory? With such a command, I would run it in my Dockerfile
itself, causing the Docker image to contain the cache with all the compiled build dependencies.
What I've tried:
go mod download
: This only downloads the dependencies; it does not compile them.- I do have this working with a temporary workaround: I created a barebones
main.go
that imports all the dependencies, and rungo build
within myDockerfile
to populate the cache. As mentioned, this does solve my problem, but it feels like a bit of a hack. Additionally, if the dependencies change in the future, it requires someone to change this as well, which isn't ideal. - A lot of the answers I saw online for this involve CI/CD. With CI/CD, the container just has a partition mounted to the host, which contains a cache that is persisted after runs. This does not solve my immediate problem, which is for building the container itself.
Since the issues (1, 2) in the golang repository are still open, all that we can do is "hacking", I think. So, we can do something like that for the dependencies caching and pre-compilation as a separate docker layer:
Without this trick, the building (
docker buildx build --platform linux/amd64,linux/arm64 ...
) takes about 9 minutes, with it ~6 minutes (profit 30%). But the pre-compilation step becomes longer by ~40%.