Use Docker layer caching with docker-compose build (not just docker)

Hi,

I spent some time getting my workflows to work with the docker layer caching as described in the blog by Docker: Docker Github Actions - Docker Blog

This works fine for building the images with Docker:

      - name: Set up Docker Buildx
        id: buildx        
        uses: docker/setup-buildx-action@master

      - name: Cache Docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-step1-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-buildx-

      - name: Build and push images
        uses: docker/build-push-action@v2
        with:
          push: false
          builder: ${{ steps.buildx.outputs.name }}
          tags: repo/step1:latest
          file: ./Dockerfile.step1
          context: .
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache

And I have 1 more container build like that (step2).

I have a docker-compose setup to run unit tests & integration tests with a whole bunch of docker-compose specific config around environment variables, volumes, entrypoints, etc.

So I am running these tests using docker-compose. Problem is docker-compose doesn’t use the images built by Docker. I did a lot of searching and googling and tried lots of things, but everything I found doesn’t seem to help to get it to work in GitHub actions.

Latest try (after the docker build steps above):

      - name: Build the stack
        run: COMPOSE_DOCKER_CLI_BUILD=1 docker-compose build

Doesn’t help, docker compose starts rebuilding both containers from scratch. Also doing docker-compose up doesn’t help, it starts pulling the images from docker hub.

Anyone knows the solution? Could be that I’m missing something, but most examples of docker layer caching (with github actions) doesn’t seem to cover docker-compose.

Full workflow and runs here: Docker caching by valentijnscholten · Pull Request #60 · valentijnscholten/django-DefectDojo · GitHub

Valentijn

1 Like

Added a basic PoC here where I build with docker-build-push action and then use docker-compose up with --no-build

Locally on my machine this works fine. Docker-compose uses the images build by docker. On GitHub actions it doesn’t work. the jobs fails as it says the image is not there.

ok, found the solution. I realized that maybe the docker-build-and-push action didn’t actually do anything with the generated image, i.e. it was not made available to the runner / docker. Turns out this is true and even documented:

Once you know what you’re looking for, it’s easy…

In case the link dies, the solution is to add load: True to the docker-build-and-push action:

- name: Build
        uses: docker/build-push-action@v2
        with:
          push: false
          load: true
          tags: valentijn/app:latest
          builder: ${{ steps.buildx.outputs.name }}
          file: ./Dockerfile
          context: .
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache

Note that there’s a bug that makes the cache grow and grow if you do it this way. There’s a fix here.