-
Notifications
You must be signed in to change notification settings - Fork 335
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
Proposal: Hermetic and Reproducible Docker files #111
Comments
Is it possible to combine both approaches? Similar to what Agones does at the moment (except the go modules), using Makefile.
And then to speed up the building of images during developement we can modify Docker mounts at step 2 adding the local changes.
Or just build everything outside of Docker with local Go and proceed directly to step 3. However I'm only guessing, didn't tested that yet. |
Looking at https://docs.docker.com/v17.09/engine/userguide/eng-image/baseimages/ and https://docs.docker.com/v17.09/engine/userguide/eng-image/multistage-build/ docker is definitely advocating for Build within Docker. Based on https://groups.google.com/forum/#!searchin/golang-nuts/go$20mod%7Csort:date/golang-nuts/FWHKA3ZGSg4/R-RaONB6BwAJ, they mention using vendor mode for go mod will work. I think for either approach we are not going to be able to avoid base image because of all the tooling that's involved. I tried to abstract a lot of it via |
Agones has a bug to move to go modules. googleforgames/agones#625. There's a pull request to add go mod support for us, #106. That's what the state is. If we want to do build within docker approach I think we'd still need to support local builds as a first class citizen. That way developers can do things like debug unit tests (more coming later, #115). I worry that build in docker and then use those binaries for local will break that flow. Golang creates artifacts in pkg/ which are probably useful debug symbols that will be lost. For example, I use vscode to debug the unit tests that I've created. A simple fix to this is to just use the Makefile to build the docker images and local binaries for automation. That way both flows are kept in sync. make install-toolchain
make all-protos
make all
make test Lastly, I'll need to follow up on vendor/ ing. My worry is that it'll be killed off and we'll be left stalling on upgrading to a later go version to readdress this problem. vendor/ does solve the download dependency issue very nicely though. |
BTW there’s a switch in Agones Makefile to to do this: |
My bias is to prefer what the best practices are and start with that. I don't see other projects doing what agones has done where the build process is done within docker driven by make. It's usually the inverse. To me we should split the concerns where the make assumes a reasonable build environment and the dockerfile provides one. That way the dockerfile can build open match the same way it's done locally. |
Golang team has this to say about vendor/ing. It's not going away and you can use it with go mod. go mod caching is very painful right now in the CI builds. It's the main source of failures because if any of the dependencies time out the whole build fails and we pull deps twice. More context: |
Some notes.
It looks like there's a movement to eliminate $GOPATH/pkg:
I'm not sure however how this all works with VS Code go debugger as didn't use it. In Agones the contents of .gocache is persisted across docker builds: https://github.com/GoogleCloudPlatform/agones/blob/master/build/Makefile#L106 Also looking at https://docs.docker.com/v17.09/engine/userguide/eng-image/baseimages/#create-a-simple-parent-image-using-scratch: they compile the code of 'hello' inside the Docker there but write it out to mounted directory. And then the binary is copied as-is into scratch container. BTW 'go mod' PR in Agones was merged, and |
The killing pkg/ is interesting I'll definitely look more into that. |
Currently the Open Match Dockerfiles are pulling code from multiple sources.
Let's see backendapi as an example.
The problem with this is the code for Open Match is pulled from multiple places, a bit from the local checkout and most from the upstream branch of Open Match. This build is problematic since it makes development more difficult and the build output is not consistent.
I'd like to propose 2 ways to build docker images.
Build within Docker
Example: https://github.com/GoogleCloudPlatform/open-match/pull/98/files
With this approach all the building happens within a docker image. The current approach in the example would be to do the following:
Baseline image that has the codebase and dependencies.
Creates a minimal image that just has the output binary. Everything is built within docker.
Advantages
Build Locally Copy to Docker Image
An alternative approach is to build outside of docker and simply copy the binary inside.
Example: https://github.com/jeremyje/open-match/blob/buildsys/cmd/backendapi/Dockerfile
This example does 2 things, create a user which we should do anyways but assumes the binary is built outside already.
Advantages
The text was updated successfully, but these errors were encountered: