kafka-ui
kafka-ui copied to clipboard
:rocket: Add Dockerhub publish during release
What changes did you make? (Give an overview) Add login to dockerhub and push image to it in main workflow Fixes #237
Is there anything you'd like reviewers to focus on? Secrets names may need to be changed based on what is currently available (no visibility on it)
How Has This Been Tested? (put an "x" (case-sensitive!) next to an item)
- [x] Yes, on my forked project with own credentials
Checklist (put an "x" (case-sensitive!) next to all the items, otherwise the build will fail)
- [x] I have performed a self-review of my own code
Check out Contributing and Code of Conduct
Hi, I spent some time last days to on that and mostly struggled with my own station to have quicker local builds... Anyway I also took into account https://github.com/kafbat/kafka-ui/issues/349 to go with a solution that would support it.
So here are 2 versions that work the same, let me know which one your prefer.
In both, I had to activate containerd as builder, for some different reasons (being able to load multi platforms images & preserve provenance attestations)
With docker save / docker load mechanism : https://github.com/giom-l/kafka-ui/blob/feat/improve_docker_publish/.github/workflows/save_load.yml
With containerd all along (using oci output & ctr to reuse the produced image)
https://github.com/giom-l/kafka-ui/blob/feat/improve_docker_publish/.github/workflows/with_ctr.yml
All produced images can be found in all 3 repositories :
- Github packages: https://github.com/giom-l/kafka-ui/pkgs/container/kafka-ui
- Dockerhub : https://hub.docker.com/repository/docker/gocho/kafka-ui/tags
- ECR public : https://gallery.ecr.aws/j4u0y1h1/kafka-ui?page=1
For ECR, my workflow uses OIDC provider . It would be the same with classic credentials (I saw some in your other workflows) and even be less verbose by using this action that would allow something like
- name: Push to ECR
id: ecr
uses: jwalton/gh-ecr-push@v2
with:
access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
region: us-east-1
local-image: kafka-ui:temp
image: <repo>/kafka-ui:main, <repo>/kafka-ui:<sha>
Hi, I spent some time last days to on that and mostly struggled with my own station to have quicker local builds... Anyway I also took into account #349 to go with a solution that would support it.
So here are 2 versions that work the same, let me know which one your prefer. In both, I had to activate
containerdas builder, for some different reasons (being able to load multi platforms images & preserve provenance attestations)With docker save / docker load mechanism : https://github.com/giom-l/kafka-ui/blob/feat/improve_docker_publish/.github/workflows/save_load.yml
With containerd all along (using
ocioutput &ctrto reuse the produced image) https://github.com/giom-l/kafka-ui/blob/feat/improve_docker_publish/.github/workflows/with_ctr.ymlAll produced images can be found in all 3 repositories :
- Github packages: https://github.com/giom-l/kafka-ui/pkgs/container/kafka-ui
- Dockerhub : https://hub.docker.com/repository/docker/gocho/kafka-ui/tags
- ECR public : https://gallery.ecr.aws/j4u0y1h1/kafka-ui?page=1
For ECR, my workflow uses OIDC provider . It would be the same with classic credentials (I saw some in your other workflows) and even be less verbose by using this action that would allow something like
- name: Push to ECR id: ecr uses: jwalton/gh-ecr-push@v2 with: access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} region: us-east-1 local-image: kafka-ui:temp image: <repo>/kafka-ui:main, <repo>/kafka-ui:<sha>
@giom-l thank you for the analysis. I'd prefer using docker save/load mechanism to have the same approach between different workflows (for example, e2e-run.yml, already uses this approach).
Can you update the PR branch with this approach so we can proceed with the review? Thank you
Sorry for the delay ! I updated the PR using the save/load mechanism as requested. I also impacted the release workflow that I forgot initially.
For the ECR publish, it's still "WIP" as I would need some informations about how you want to authenticate and where (ecr public ?)
I updated the PR using the save/load mechanism as requested.
Thank you.
about how you want to authenticate
I guess, we could auth the same way we do here (unless you have a better suggestion?)
and where (ecr public ?)
Yes, as we (accidentally) had one before (source).
Can I also ask you to refactor the workflows to use reusable workflows to reduce the copypaste in these workflows? I can take a look myself later as an alternative.
Sure. Just a question about how you see that :) One reusable action per target registry (ecr, github, ecr) ? Or one reusable action (something like image-publish) that push to all registries (but I'm not sure how it behave if one of them fails. Can we still rerun just a part of it ?) ?
I thought about one generic reusable action that will take parameters (like registry, credentials) but since ECR login is not the same as the other, I'm not sure it's doable.
Let me know what you think
I see that as follows:
- A workflow to run on a push to main
- A workflow to run on a release
- Both 1) and 2) call another workflow to build an image (docker-build.yml) and a workflow to publish one (docker-publish.yml)
- docker-publish.yml contains 3 jobs for each registry (gh, ecr, dockerhub) In this case we can extract common parts for each workflow and keep publishing as separate jobs within a separate calling workflow.
Feel free to use e2e-*.yml workflows as templates, we have the basic required stuff there (calling other workflows, passing arguments through, transferring artifacts between jobs, etc.)
Can we still rerun just a part of it
Yes, we would be able to rerun separate jobs within a workflow like this:
Hello
I gave this some time yesterday and made it work as follows (PR udpated) :
- 1 docker_build.yml workflow
- 1 docker_publish.yml workflow, which itself calls 3 differents workflows :
- 1 publish_ecr.yml
- 1 publish_dockerhub.yml
- 1 publish_ghcr.yml
About extracting common parts for the three publish jobs : It seems not really useful to me since it's only a matter of downloading artifacts & configuring docker daemon, which can't be shared between jobs.
However, I also experienced another solution that can be found in this branch : The main & release job will call the docker_publish and this one is more generic (only the logging part isn't) and uses matrix instead of calling others workflows. I find this solution to be more elegant (less duplicated code, no intermediary workflow)
Let me know what you think and I'll finalize the PR with the solution that is preferred on your side.
Hey, sorry for the delay.
One more thing, can we get separate workflows like publish_x.yml to be separate jobs within one workflow instead? I don't see any point in making them separate workflows rather than jobs, it just adds additional overhead. Let me know what you think.
Hello,
Sure, I'll give some tests to your proposals and fix them if everything's good.
About
One more thing, can we get separate workflows like publish_x.yml to be separate jobs within one workflow instead? I don't see any point in making them separate workflows rather than jobs, it just adds additional overhead. Let me know what you think.
I totally agree. This is why I also proposed another solution that I find more elegant. You can find the workflow here
It uses matrix strategy to produce as much jobs as we want, but it remains in 1 workflow only (way more readable). The downside is about having steps that will run only in certain cases (login to target platform) but it removes duplication of code.
Let me know if it better fits what you expect and I'll port it to the PR branch :) .
Hi,
the problem with the matrix approach is that it's just one job within a workflow which will result in unnecessary re-deployments in case when one of the three deployments fails (say, we've deployed to ecr and then ghcr has failed). If we split them in three separate jobs, we won't have to redeploy on job restart. Can we adjust that?
Hello,
I'm having the same behavior between 3 jobs and a matrix that generates 3 jobs. See here, I changed a secret on my project to make the dockerhub publish fail (which happened)
If I rerun all jobs, all of them will rerun (of course)
But if I rerun the failed one, only failed one will rerun.
One can also rerun the failed job with the dedicated icon
or after selecting the failed job.
And you can see here that the previously succeeded jobs didn't rerun when the failed one restart
Or am I missing your point ? In any case, if you confirm you prefer 3 separates jobs in the same workflow (with duplicated code though), that's fine for me too :)
I'm having the same behavior between 3 jobs and a matrix that generates 3 jobs.
Oh, thanks for correcting me! I've seen matrix workflows in action but haven't used them personally before so I thought the part we need was missing :)
Besides the minor comments I've left (and other possible things to clean up you manage to find) I'd need to get our credentials for ECR and we can merge. Thank you very much for the high-quality PR and continuous cooperation, and I am sorry for the delays on my part :)
Hello,
I just updated the PR to use matrix workflows and removed old workflows that contained some hardcoded strings.
It should work with no issue as soon as :
- The secrets used in the workflows are correct (let me know if I need to change some names)
secrets.DOCKERHUB_USERNAME
secrets.DOCKERHUB_TOKEN
- You are using ECR public and not private.
- AWS authentication is handled with an AWS role
secrets.AWS_ROLE
This is a personal preference to use role over static credentials. If you prefer to stick with credentials, it will be easy to change. Let me know.
- The owner/repository names are the same for all 3 registries (
kafbat/kafka-ui) If that is not the case, we'll need to introduce another variable "OWNER" in thedocker_publish.ymlworkflow to take care of this difference.
@giom-l thanks for your first (and a high quality one!) contribution to kafbat UI! I'll be taking a look at how this behaves now.
@giom-l any clues on what's the unknown/unknown image arch we've got?
https://github.com/kafbat/kafka-ui/pkgs/container/kafka-ui/285510516?tag=07f0e0e75471a44be52782b06d0362c42820cba1
It reminds me of something about provenance but can't remember exactly what ATM.
I'm pretty sure I tried multiple stuffs to get rid of that unsuccessfully. I think that in the end, I preferred to keep provenance attestations with unknown arch over not having them at all.
I just found this discussion that seem related : https://github.com/orgs/community/discussions/45969
But there does not seem to be proper answer (get rid of provenance, pinning version that seem to not work anymore...)