Skip to content
Latchkey

Publish AnythingLLM Docker image on Release (amd64 & arm64) workflow (Mintplex-Labs/anything-llm)

The Publish AnythingLLM Docker image on Release (amd64 & arm64) workflow from Mintplex-Labs/anything-llm, explained and optimized by Latchkey.

B

CI health: B - good

Point runs-on at Latchkey and get job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: Mintplex-Labs/anything-llm.github/workflows/build-and-push-image-semver.yamlLicense MITView source

What it does

This is the Publish AnythingLLM Docker image on Release (amd64 & arm64) workflow from the Mintplex-Labs/anything-llm repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Publish AnythingLLM Docker image on Release (amd64 & arm64)

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

on:
  release:
    types: [published]

jobs:
  push_multi_platform_to_registries:
    name: Push Docker multi-platform image to multiple registries
    runs-on: ubuntu-22.04-arm
    permissions:
      packages: write
      contents: read
    steps:
      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Check if DockerHub build needed
        shell: bash
        run: |
          # Check if the secret for USERNAME is set (don't even check for the password)
          if [[ -z "${{ secrets.DOCKER_USERNAME }}" ]]; then
            echo "DockerHub build not needed"
            echo "enabled=false" >> $GITHUB_OUTPUT
          else
            echo "DockerHub build needed"
            echo "enabled=true" >> $GITHUB_OUTPUT
          fi
        id: dockerhub

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          version: v0.22.0
      
      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        # Only login to the Docker Hub if the repo is mintplex/anythingllm, to allow for forks to build on GHCR
        if: steps.dockerhub.outputs.enabled == 'true' 
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      
      - name: Log in to the Container registry
        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
        with:
          images: |
            ${{ steps.dockerhub.outputs.enabled == 'true' && 'mintplexlabs/anythingllm' || '' }}
            ghcr.io/${{ github.repository }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}

      - name: Build and push multi-platform Docker image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./docker/Dockerfile
          push: true
          sbom: true
          provenance: mode=max
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
      
      # For Docker scout there are some intermediary reported CVEs which exists outside
      # of execution content or are unreachable by an attacker but exist in image.
      # We create VEX files for these so they don't show in scout summary. 
      - name: Collect known and verified CVE exceptions
        id: cve-list
        run: |
          # Collect CVEs from filenames in vex folder
          CVE_NAMES=""
          for file in ./docker/vex/*.vex.json; do
            [ -e "$file" ] || continue
            filename=$(basename "$file")
            stripped_filename=${filename%.vex.json}
            CVE_NAMES+=" $stripped_filename"
          done
          echo "CVE_EXCEPTIONS=$CVE_NAMES" >> $GITHUB_OUTPUT
        shell: bash

      # About VEX attestations https://docs.docker.com/scout/explore/exceptions/
      # Justifications https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications
      - name: Add VEX attestations
        env:
          CVE_EXCEPTIONS: ${{ steps.cve-list.outputs.CVE_EXCEPTIONS }}
        run: |
          echo $CVE_EXCEPTIONS
          curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
          for cve in $CVE_EXCEPTIONS; do
            for tag in "${{ join(fromJSON(steps.meta.outputs.json).tags, ' ') }}"; do
              echo "Attaching VEX exception $cve to $tag"
              docker scout attestation add \
              --file "./docker/vex/$cve.vex.json" \
              --predicate-type https://openvex.dev/ns/v0.2.0 \
              $tag
            done
          done
        shell: bash

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Publish AnythingLLM Docker image on Release (amd64 & arm64)
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
on:
  release:
    types: [published]
 
jobs:
  push_multi_platform_to_registries:
    timeout-minutes: 30
    name: Push Docker multi-platform image to multiple registries
    runs-on: latchkey-small-arm
    permissions:
      packages: write
      contents: read
    steps:
      - name: Check out the repo
        uses: actions/checkout@v4
 
      - name: Check if DockerHub build needed
        shell: bash
        run: |
          # Check if the secret for USERNAME is set (don't even check for the password)
          if [[ -z "${{ secrets.DOCKER_USERNAME }}" ]]; then
            echo "DockerHub build not needed"
            echo "enabled=false" >> $GITHUB_OUTPUT
          else
            echo "DockerHub build needed"
            echo "enabled=true" >> $GITHUB_OUTPUT
          fi
        id: dockerhub
 
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          version: v0.22.0
      
      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        # Only login to the Docker Hub if the repo is mintplex/anythingllm, to allow for forks to build on GHCR
        if: steps.dockerhub.outputs.enabled == 'true' 
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      
      - name: Log in to the Container registry
        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
        with:
          images: |
            ${{ steps.dockerhub.outputs.enabled == 'true' && 'mintplexlabs/anythingllm' || '' }}
            ghcr.io/${{ github.repository }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
 
      - name: Build and push multi-platform Docker image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./docker/Dockerfile
          push: true
          sbom: true
          provenance: mode=max
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
      
      # For Docker scout there are some intermediary reported CVEs which exists outside
      # of execution content or are unreachable by an attacker but exist in image.
      # We create VEX files for these so they don't show in scout summary. 
      - name: Collect known and verified CVE exceptions
        id: cve-list
        run: |
          # Collect CVEs from filenames in vex folder
          CVE_NAMES=""
          for file in ./docker/vex/*.vex.json; do
            [ -e "$file" ] || continue
            filename=$(basename "$file")
            stripped_filename=${filename%.vex.json}
            CVE_NAMES+=" $stripped_filename"
          done
          echo "CVE_EXCEPTIONS=$CVE_NAMES" >> $GITHUB_OUTPUT
        shell: bash
 
      # About VEX attestations https://docs.docker.com/scout/explore/exceptions/
      # Justifications https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications
      - name: Add VEX attestations
        env:
          CVE_EXCEPTIONS: ${{ steps.cve-list.outputs.CVE_EXCEPTIONS }}
        run: |
          echo $CVE_EXCEPTIONS
          curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
          for cve in $CVE_EXCEPTIONS; do
            for tag in "${{ join(fromJSON(steps.meta.outputs.json).tags, ' ') }}"; do
              echo "Attaching VEX exception $cve to $tag"
              docker scout attestation add \
              --file "./docker/vex/$cve.vex.json" \
              --predicate-type https://openvex.dev/ns/v0.2.0 \
              $tag
            done
          done
        shell: bash
 

What changed

2 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow