Add docker layer caching (#3318)#3358
Conversation
None of the workflows have the copyright banner, should i add it anyway? |
|
saves ~3m when only backend changes and ~1m when both backend and frontend changes |
There was a problem hiding this comment.
Pull request overview
This PR implements Docker layer caching for GitHub Actions to speed up CI builds. The caching strategy builds and stores Docker image layers when pushing to the develop branch, which are then reused during PR CI runs. This optimization addresses issue #3318 by significantly reducing build times when dependencies haven't changed.
Changes:
- Added new workflow
.github/workflows/docker-build-cache.ymlthat builds Docker images on push to develop and stores layers in GitHub Actions cache - Modified
.github/workflows/pull_request_automation.ymlto use cached layers during PR builds and removed the--buildflag from the startup script since images are now pre-built - Optimized
docker/Dockerfilelayer ordering by copying package files first, running installations, then copying source code to maximize cache effectiveness
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
.github/workflows/docker-build-cache.yml |
New workflow that builds and caches Docker images on develop branch pushes |
.github/workflows/pull_request_automation.yml |
Updated to leverage cached layers and use pre-built images instead of building during startup |
docker/Dockerfile |
Restructured to optimize layer caching by reordering COPY and RUN commands |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
please address copilot review. no need about the copyright banner there |
| @@ -0,0 +1,55 @@ | |||
| permissions: read-all | |||
There was a problem hiding this comment.
this file needs to be tracked in the dependabot configuration
There was a problem hiding this comment.
IntelOwl/.github/dependabot.yml
Lines 194 to 202 in 0b4e564
already tracked?
There was a problem hiding this comment.
wait nvm, does this ignore all action updates? why so?
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Removed cache-to configuration for Docker builds.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (2)
.github/workflows/docker-build-cache.yml:33
- This workflow builds images only to populate the GHA layer cache, but
load: truealso imports the image into the runner’s local Docker daemon, increasing runtime and disk usage without being needed here. Consider removingload: true(keepcache-to/cache-from) unless subsequent steps in this workflow actually run containers from these images.
- name: Build
uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile
push: false
load: true
tags: intelowlproject/intelowl:ci
build-args: |
.github/workflows/docker-build-cache.yml:55
- Same as the main-image job:
load: trueis unnecessary if the workflow’s only goal is to export BuildKit cache layers. Droppingloadwill typically reduce time and disk consumption on the runner.
- name: Build
uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile_nginx
push: false
load: true
tags: intelowlproject/intelowl_nginx:ci
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I would like to test these changes on my fork again Lines 54 to 56 in 8419ace I would like to add cache mounts https://docs.docker.com/build/ci/github-actions/cache/#cache-mounts |
mlodic
left a comment
There was a problem hiding this comment.
the problem about integrating this change is that it is difficult to evaluate whether this works properly or not because that github action would work only when this change is merged into master.
So, to merge this PR, I need that you first merge this into your own fork and share the github action results that prove that this works as intended
|
|
||
| COPY requirements/project-requirements.txt $PYTHONPATH/project-requirements.txt | ||
| COPY requirements/certego-requirements.txt $PYTHONPATH/certego-requirements.txt | ||
| COPY requirements/django-server-requirements.txt $PYTHONPATH/requirements/django-server-requirements.txt |
There was a problem hiding this comment.
no, this must be installed only on local environments otherwise it would install watchman also in production environments
There was a problem hiding this comment.
this change only copies the file, pip install is run on this from watchman install script, which is only run when watchman isnt false, which is only set for tests. even without this change, this file is copied, just with the rest of the source code
I tested before making this PR, will test again after making review changes when nothing is cached it takes approximately the same time as before -> https://github.com/intelowlproject/IntelOwl/actions/runs/22382367884/job/64785856226?pr=3358 |
thanks for sharing all the info, it's appreciated please go on experimenting |
|
Cache mounts didnt offer much improvement so i removed them |
|
i will test more scenarios (partially cached) and do some last changes before this is ready for review |
|
@gqvz that's fine as long as you are keep constant communication, thank you. I am curious about the additional tests |
|
only backend changes - https://github.com/gqvz/IntelOwl/actions/runs/22805585413/job/66154081670?pr=7 worst case is when any changes are made to pip requirements, time taken for that case is around 20-30s more than what it normally takes (without any caching anywhere) one question - for backend tests, why are we building the frontend and copying the files?, can easily skip all the frontend stuff |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
to make the final image lighter |
no like i meant, for backend tests ci we can completely skip everything frontend related, we are building and copying but it isnt being used for ci tests |
mlodic
left a comment
There was a problem hiding this comment.
I am asking some questions to understand the choices made, please answer accordingly. thank you
| - name: Set image repo | ||
| run: echo "IMAGE_REPO=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Set up Docker Buildx |
There was a problem hiding this comment.
the order of this and login to ghcr is different between the 2 yml files, is there a reason?
There was a problem hiding this comment.
sorry that wasnt intentional, i'll fix this rn
| default = "false" | ||
| } | ||
|
|
||
| variable "CACHE_REPO" { |
There was a problem hiding this comment.
can you explain how this variable is used and why it is empty?
There was a problem hiding this comment.
this is so i dont have to hardcode the repo intelowlproject/intelowl into the code, because that wouldnt work for forks, it is set from env vars
| target "redis" { | ||
| dockerfile-inline = "FROM redis:6.2.7-alpine" | ||
| tags = ["redis:6.2.7-alpine"] | ||
| } |
There was a problem hiding this comment.
I am not sure about these declarations. I mean, this duplicates the code that already exists in the docker compose files. This could pose possible problems in terms of maintainance. Is this file and all of these configuration necessary?
There was a problem hiding this comment.
broadly speaking, we should build the images in CI like we do in dev and prod, using the same docker composes, to ensure that they actually reproduce the right environments.
There was a problem hiding this comment.
i couldnt find any other way to run build and pulls in parallel
compose up builds and and pulls images in parallel, but it doesnt store cache anywhere, so to store cache we need to build the image separately, but then if we dont use bake to build and pull, the build and pulls will be sequential and the whole process takes more time
i dont think there will be any difference in the final image depending on how its built, as long as the repodownloader and watchman and othe env vars are set the same
about the redis and postgres declaration, i undestand that these may be problematic to maintain, i'll try to find alternatives
ok but the solution shouldn't make things too complex. Some speed improvs can really make the future maintainance problematic, so adding too much additional stuff can be counter productive. Please compromise for simpler solutions |
|
runtime is about the same +- 10s with this method |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
|
I prefer this solution, thanks.
Can you show the error you mentioned? And can you link the very last tests? Then I think we are gtg |
^ falls back to local cache everything is cached (no changes to any packages) - https://github.com/gqvz/IntelOwl/actions/runs/22853788781/job/66288738273?pr=8 i can rerun the tests for changes to packages but the results will be almost the same as the tests before |
Improvement #3318 (this issue may have multiple PRs)
Description
Add docker layer caches to ghcr. Docker image is built and its layers are stored on push to develop. These layer caches are used when running tests from PR CI
Type of change
Checklist
develop# This file is a part of IntelOwl https://github.com/intelowlproject/IntelOwl # See the file 'LICENSE' for copying permission.Ruff) gave 0 errors. If you have correctly installed pre-commit, it does these checks and adjustments on your behalf.DeepSource,Django Doctorsor other third-party linters have triggered any alerts during the CI checks, I have solved those alerts.