sxs-collaboration / spectre

SpECTRE is a code for multi-scale, multi-physics problems in astrophysics and gravitational physics.
https://spectre-code.org
Other
162 stars 191 forks source link

Build Docker container on CI #3493

Open nilsvu opened 3 years ago

nilsvu commented 3 years ago

Feature request:

It would be nice if CI could build and push the Docker container, without disrupting other CI runs or user environments. Currently we have to do the "Docker dance": When a PR updates the Dockerfile, a core dev builds the container and pushes it to sxscollaboration/spectrebuildenv:latest. This may break all other PRs and user envs until the PR that adjusts to the new container has been merged and rebased-on.

Here's a wish list how I would like updating the container to work instead:

This is a possible procedure to achieve the above:

  1. Edit the Dockerfile. Once you open a PR, GitHub will build the container, tag it with the commit hash and push it to DockerHub. The push requires approval by a core dev. No other CI runs or user environments will be disrupted because they still refer to the old container.
  2. Make note of the new container tag. It's the commit hash of the latest commit that edits the container. In a follow-up commit that requires the new container, update the container tag in these places in the repo:

    • Metadata.yaml
    • Tests.yaml
    • .devcontainer.json

    You will only be able to merge the PR that edits the Dockerfile once these places refer to the new tag.

I think this would work, but I haven't figured out how to handle permissions yet. When the CI workflow is triggered by the PR that updates the Dockerfile, it doesn't have access to the DockerHub secrets. So it can't push the new container, nor should it publish anything without approval. But the container needs to get published before the PR gets merged, so the PR can include a commit that upgrades to the new container, and run tests on it. We can wrap the DockerHub secrets in a GitHub environment that the action requests access to. Then maybe we can trigger the action from every PR that edits the Dockerfile, and only approve it when we want the image published. Or we trigger the build-and-push with a special PR comment. Any suggestions are welcome here.

knelli2 commented 2 years ago

I'm now trying to do something similar to this, but not exactly the same.

My idea is to have pre-built executables in the container that people can run without having to worry about building spectre. However, this makes the image fairly large, so we wouldn't want to use this image for CI. Also the image with pre-built executables doesn't need all the extra compilers that are needed for CI. Only one is needed. Here are the different tags I propose for editing the current Dockerfile:

Regarding @nilsvu's suggestions, I guess we'd only have to worry about when somebody changed the base or ci parts of the Dockerfile, as those are what GitHub CI would need. Then, for the demo tag, this image could be updated every release so that we maintain up-to-date executables in the container.

Thoughts on this would be appreciated. I'm going to test this locally and on my personal DockerHub to see how it works out.

knelli2 commented 2 years ago

From preliminary tests from building on my local computer, the current image on sxscollaboration/spectrebuildenv is ~8.5G. Here are the sizes for each of the images I have (as of 8/17/22):

Already these are individually smaller than our current image which I think is really good. Especially base.

nilsvu commented 2 years ago

I think this sounds great. Having a demo container with a spectre build and ParaView installed would be very useful for tutorials. A few questions:

knelli2 commented 2 years ago
nilsvu commented 2 years ago

Quick note: I suggest you put the demo container build in the PostRelease.yaml workflow. It runs after the release is published, and it's ok if it runs for a while.