skip to Main Content

Here I have two workflows under a job. The only target we want to achieve is that, we want to reuse the container images by using cache or some other means. Similar way we do for node_modules

jobs:
    build:
        name: build
        runs-on: [self-hosted, x64, linux, research]
        container:
          image: <sample docker image>
        env:
          NPM_AUTH_TOKEN: <sample token>
        steps:
          - uses: actions/checkout@v2
          - name: Install
            run: |
              npm install
          - name: Build
            run: |
          npm build
    Test:
        name: Test Lint
        runs-on: [self-hosted, x64, linux, research]
        container:
          image: <sample docker image>
        env:
          NPM_AUTH_TOKEN: <sample token>
        steps:
          - uses: actions/checkout@v2
          - name: Install Dependencies
            run: npm ci
          - name: Lint Check
            run: npm run lint

2

Answers


  1. In general, data is not shared between jobs in GitHub Actions (GHA). jobs actually will run in parallel on distinct ephemeral VMs unless you explicitly create a dependency with needs

    GHA does provide a cache mechanism. For package manager type caching, they simplified it, see here.

    For docker images, you either can use docker buildx cache and cache to a remote registry (including ghcr), or use the GHA cache action, which probably is easier. The syntax for actions/cache is pretty straightforward and clear on the page. For buildx, documentation always has been a bit of an issue (largely, I think, because he people building it are so smart that they do not realize how much we do not understand what is in their hearts), so you would need to configure the cache action, and then buildx to cache it.

    Alternatively, you could do docker save imagename > imagename.tar and use that in the cache. There is a decent example of that here. No idea who wrote it, but it does the job.

    Login or Signup to reply.
  2. I would suggest using the Docker’s Build Push action for this purpose. Through the build-push-action, you can cache your container images by using the inline cache, registry cache or the experimental cache backend API:

    Inline cache

    name: Build and push
    uses: docker/build-push-action@v2
    with:
        context: .
        push: true
        tags: user/app:latest
        cache-from: type=registry,ref=user/app:latest
        cache-to: type=inline
    

    Refer to the Buildkit docs.

    Registry Cache

    name: Build and push
    uses: docker/build-push-action@v2
    with:
        context: .
        push: true
        tags: user/app:latest
        cache-from: type=registry,ref=user/app:buildcache
        cache-to: type=registry,ref=user/app:buildcache,mode=max
    

    Refer to Buildkit docs.

    Cache backend API

    name: Build and push
    uses: docker/build-push-action@v2
    with:
        context: .
        push: true
        tags: user/app:latest
        cache-from: type=gha
        cache-to: type=gha,mode=max
    

    Refer to Buildkit docs.

    I personally prefer using the Cache backend API as its easy to setup and provides a great boost in reducing the overall CI pipeline run duration.


    By looking at the comments, it seems you want to share Docker cache between workflows. In this case you can share Docker containers between jobs in a workflow using this example:

    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          -
            name: Checkout
            uses: actions/checkout@v2
          -
            name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v1
          -
            name: Build and push
            uses: docker/build-push-action@v2
            with:
              context: .
              file: ./Dockerfile
              tags: myimage:latest
              outputs: type=docker,dest=/tmp/myimage.tar
          -
            name: Upload artifact
            uses: actions/upload-artifact@v2
            with:
              name: myimage
              path: /tmp/myimage.tar
    
      use:
        runs-on: ubuntu-latest
        needs: build
        steps:
          -
            name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v1
          -
            name: Download artifact
            uses: actions/download-artifact@v2
            with:
              name: myimage
              path: /tmp
          -
            name: Load Docker image
            run: |
              docker load --input /tmp/myimage.tar
              docker image ls -a
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search