Reputation: 3418
Is there any way to cache docker-compose so that it will not build again and again? here is my action workflow file:
name: Github Action
on:
push:
branches:
- staging
jobs:
test:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: Bootstrap app on Ubuntu
uses: actions/setup-node@v1
with:
node-version: '12'
- name: Install global packages
run: npm install -g yarn prisma
- name: Install project deps
if: steps.cache-yarn.outputs.cache-hit != 'true'
run: yarn
- name: Build docker-compose
run: docker-compose -f docker-compose.test.prisma.yml up --build -d
I want to cache the docker build step. I have tried using if: steps.cache-docker.outputs.cache-hit != 'true' then only build
but didn't work.
Upvotes: 28
Views: 18480
Reputation: 3265
This answer builds on top of what the user byte said and relates to several other questions.
It is suited for situations where you only want to cache the layers, but not push actual images to a registry. I.e. when you want to use cache type=gha
(see Docker Documentation), like recommended in many places. I use this style for temporary images like integration testing images that I don't need to store to a registry, but still want to cache.
build:
permissions:
id-token: write
contents: read
name: "Prebuild docker images"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: docker/bake-action@master
with:
push: false
load: true
files: |-
docker-compose.yml
docker-compose-cache.json
docker-compose-cache.json, replace <GH_ORG>
, <REPO>
and <SERVICE>
with your own references. The scope
does not strictly need to match any of those, any unique string is fine.
{
"target": {
"service-name": {
"cache-from": [
"type=gha,scope=<GH_ORG>/<REPO>/<SERVICE>"
],
"cache-to": [
"type=gha,mode=max,scope=<GH_ORG>/<REPO>/<SERVICE>"
],
"output": [
"type=docker"
]
},
}
}
Upvotes: 2
Reputation: 687
This question is old, but I found myself trying to solve precisely the same problem. After reading many different answers and spending lots of time, I eventually found a decent solution.
My workflow file now looks like this:
jobs:
build:
name: Integration tests
runs-on: ubuntu-22.04
# I need "packages: write" to access GHCR.
# More about permissions here: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
permissions: write-all
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v2
- name: Build docker-compose
# Before the cache, it was "run: docker compose build".
run: docker buildx bake --file docker-compose.yml --file docker-compose-cache.json
...
And in the docker-compose-cache.json
file, I have the following:
{
"target": {
"service-name": {
"cache-from": [
"type=registry,ref=ghcr.io/MY_GITHUB_ORG_NAME/service-name:cache"
],
"cache-to": [
"type=registry,ref=ghcr.io/MY_GITHUB_ORG_NAME/service-name:cache"
],
"output": [
"type=docker"
]
}
}
}
For each service in docker-compose.yml
, I add a target
in docker-compose-cache.json
. docker buildx bake
takes build instructions from docker-compose.yml
and cache instructions from docker-compose-cache.json
.
This way, I can still use docker-compose up --build
locally as usual.
As you may note, I'm using the GitHub container registry instead of the GitHub actions cache because GHCR has no limitation for cache size.
Upvotes: 21
Reputation: 781
If using docker/bake-action
or docker/build-push-action
& want to access a cached image in subsequent steps -
load:true
to save the imageExample:
...
name: Build and push
uses: docker/bake-action@master
with:
push: false
load: true
set: |
web.cache-from=type=gha
web.cache-to=type=gha
-
name: Test via compose
command: docker compose run web tests
...
services:
web:
build:
context: .
image: username/imagename
command: echo "Test run successful!"
See the docker
team's responses;
Upvotes: 3
Reputation: 684
For those arriving here via Google, this now "supported". Or at least it is working: https://github.community/t/use-docker-layer-caching-with-docker-compose-build-not-just-docker/156049. The idea is to build the images using docker (and its cache) and then use docker compose to run (up) them.
Upvotes: 12
Reputation: 14776
What you are referring to is called "docker layer caching", and it is not yet natively supported in GitHub Actions.
This is discussed extensively in several places, like:
As mentioned in the comments, there are some 3rd party actions that provide this functionality (like this one), but for such a core and fundamental feature, I would be cautious with anything that is not officially supported by GitHub itself.
Upvotes: 12