Skip to content

GitHub Action that enables caching docker compose volumes (e.g. node_modules) and images built by docker compose

License

Notifications You must be signed in to change notification settings

datarockets/docker-compose-cache

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

Docker Compose Cache Action

Enables caching of docker compose volumes and images across builds.

Why?

We use docker compose heavily in our dev environments. Usually, in development, we have an image with an interpreter (e.g. Ruby or Node.js) and necessary system dependencies (e.g. CA certificates or SSL libraries) and install app dependencies (gems or npm packages) separately during the setup.

On macOS, bind mount volumes are painfully slow, especially when we do a lot of small writes or a lot of different file reads. So we usually use docker volumes for folders with app dependencies (e.g. vendor/bundle or node_modules).

# compose.yml

services:
  app:
    build:
      context: .
    volumes:
      - .:/home/app/app
      - vendor_bundle:/home/app/app/vendor/bundle
      - node_modules:/home/app/app/node_modules
    command: bin/dev
    ports:
      - 3000:3000

volumes:
  vendor_bundle:
  node_modules:

In addition to dockerized environment, we have bin/setup scripts in our projects that setup dev environment so the app is ready to work with. Usually it looks something like this:

# bin/setup

docker compose build
bin/npm install
bin/bundle install
bin/rails db:prepare

Ideally, on GitHub Actions, we want to just run bin/setup and then bin/lint and bin/test, without repeating setup steps and configuring dependencies such us database.

As a side-effect, we would test bin/setup script on CI and make sure new developers onboarding to the project wouldn't have additional troubles.

GitHub Actions start a fresh VM for every run and it makes bin/setup to build images and install dependencies from scratch which is slow.

We want to cache image layers and volumes with dependencies.

Usage

steps:
  - uses: actions/checkout@v4
  # buildx and newer version of compose are required for image layers caching to work:
  - uses: docker/setup-buildx-action@v3
  - uses: docker/setup-compose-action@v1
  - uses: datarockets/docker-compose-cache@v1
    with:
      volumes: |
        node_modules: ${{ hashFiles('package-lock.json') }}
  - run: bin/setup

In order to cache image layers, you would need to set cache_from and cache_to in build section for your service. It's recommended to create a separate compose.ci.yml and use it conditionally depending on whether CI env variable is set:

# compose.ci.yml

services:
  app:
    build:
      cache_from:
        - type=gha
      cache_to:
        - type=gha,mode=max
# bin/setup

if [[ -n "${CI}" ]]; then
	export COMPOSE_FILE="compose.yml:compose.ci.yml"
fi

docker compose build
# ...

Alternatives

I found out that there's an existing "Docker Compose Cache" seijikohara/docker-compose-cache-action only on release. I think it takes a bit different approach by parsing compose files and doesn't cache volumes.

About

GitHub Action that enables caching docker compose volumes (e.g. node_modules) and images built by docker compose

Resources

License

Stars

Watchers

Forks

Packages

No packages published