Hi folks! How would you build a docker image with a lein-based app in GitHub Actions? Using Multi-Stage Builds and some base image with lein?
that would be the best option
If you're interested, I've been working on unifying builds for common tooling and frameworks:
https://github.com/into-docker/into-docker
(It's similar to source-to-image
, if you've heard about that.)
There is also a Github Action:
https://github.com/into-docker/build-action
Would be interested to hear whether that matches your use case. 🙂
Thanks, that looks really well! The GH Action example would be even better if it showed how to cache the dependencies :) Do you plan to support Windows? Currently the Readme only mentions brew (though the GA Action implies Linux is also supported)
It definitely runs on Linux, but I have never added something to a Linux package repo before, so you'll have to download the release yourself (https://github.com/into-docker/into-docker/releases/tag/v1.0.0). I'll see if I can get it built on Windows, but I currently have no way of verifying the result.
It is not critical, we can use lein directly and only use into in GH. Thank you!
> The GH Action example would be even better if it showed how to cache the dependencies 🙂
I don’t have an example at hands but used to have caching ability using multistage build + docker context + local maven registry
main idea is to keep everything you need to get the dependencies in one named stage. in gh action you can build an image using two command instead of one docker build …
:
• docker build --target name_of_the_stage -t deps
• docker build -t image
second command will use result of the previouse command, so there will be no significant time penalty
Then you can run result of the first command with simple infinite loop script
From running container you can copy downloaded dependencies using docker cp
. They can be cached normally.
Using into-docker
, something like this should just work™:
- uses: actions/cache@v2
with:
path: cache-file.tar
key: ${{ runner.os }}-build
- uses: into-docker/build-action@v1
with:
image: target-image:latest
builder: intodocker/clojure
profile: default
cache-path: cache-file.tar
I guess the cache key should also include a hash of the project.clj or similar...
That sounds reasonable. In this case, it would also work without, but the cache would grow and grow whenever you change project.clj.
I am not sure how it works. I would suppose that old, unused entries get pruned... Need to do some reading 🙂
I guess into simply unpacks the archive into /.m2/repository
and then runs lein build
so if the project.clj changed, it will simply install any missing dependencies and ignore any newly unused so using the hash is not really necessary...
Yes, that's basically it. And that might mean that the ~/.m2/repository
grows and grows, unless there is a pruning mechanism like you mentioned.
> Once you create a cache, you cannot change the contents of an existing cache but you can create a new cache with a new key. according to https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows Also the example there hashes the package lock file. So it seems it is necessary after all to include some hash of dependencies ... > GitHub will remove any cache entries that have not been accessed in over 7 days.
Cool, thanks for sharing!
@yannick.scherer https://github.com/into-docker/into-docker#run-build should perhaps also link to the available builder images, which hopefully describe what they expect from the application to be able to build and run it.
I'll definitely have to do a review of builder images and whether their documentation is up-to-date. I don't necessarily want to maintain a list of those images, so maybe using Github topics is good enough: https://github.com/topics/into-docker-builder-image