Skip to content
Latchkey

Build Docker Image workflow (open-webui/pipelines)

The Build Docker Image workflow from open-webui/pipelines, 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: open-webui/pipelines.github/workflows/build-docker-image.yamlLicense MITView source

What it does

This is the Build Docker Image workflow from the open-webui/pipelines 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: Build Docker Image

on:
    workflow_call:
        inputs:
            build_args:
                required: false
                default: ""
                type: string
            cache_id:
                required: true
                type: string
            extract_flavor:
                required: false
                default: ""
                type: string
            image_name:
                required: true
                type: string
            image_tag:
                required: false
                default: ""
                type: string
            registry:
                required: false
                default: ghcr.io
                type: string

env:
    FULL_IMAGE_NAME: ${{ inputs.registry }}/${{ inputs.image_name }}

jobs:
    build-image:
        runs-on: ubuntu-latest
        permissions:
            contents: read
            packages: write
        strategy:
            fail-fast: false
            matrix:
                platform:
                    - linux/amd64
                    - linux/arm64

        steps:
            - name: Prepare
              run: |
                  platform=${{ matrix.platform }}
                  echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV

            - name: Checkout repository
              uses: actions/checkout@v4

            - name: Set up QEMU
              uses: docker/setup-qemu-action@v3

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

            - name: Log in to the Container registry
              uses: docker/login-action@v3
              with:
                  registry: ${{ inputs.registry }}
                  username: ${{ github.actor }}
                  password: ${{ secrets.GITHUB_TOKEN }}

            - name: Extract metadata for Docker images
              id: meta
              uses: docker/metadata-action@v5
              with:
                  images: ${{ env.FULL_IMAGE_NAME }}
                  tags: |
                      type=ref,event=branch
                      type=ref,event=tag
                      type=sha,prefix=git-
                      type=semver,pattern={{version}}
                      type=semver,pattern={{major}}.{{minor}}
                      ${{ inputs.image_tag }}
                  flavor: |
                      latest=${{ github.ref == 'refs/heads/main' }}
                      ${{ inputs.extract_flavor }}

            - name: Extract metadata for Docker cache
              id: cache-meta
              uses: docker/metadata-action@v5
              with:
                  images: ${{ env.FULL_IMAGE_NAME }}
                  tags: |
                      type=ref,event=branch
                  flavor: |
                      prefix=cache-${{ inputs.cache_id }}-${{ matrix.platform }}-

            - name: Build Docker image
              uses: docker/build-push-action@v5
              id: build
              with:
                  context: .
                  push: true
                  platforms: ${{ matrix.platform }}
                  labels: ${{ steps.meta.outputs.labels }}
                  outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
                  cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }}
                  cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max
                  build-args: |
                      BUILD_HASH=${{ github.sha }}
                      ${{ inputs.build_args }}

            - name: Export digest
              run: |
                  mkdir -p /tmp/digests
                  digest="${{ steps.build.outputs.digest }}"
                  touch "/tmp/digests/${digest#sha256:}"

            - name: Upload digest
              uses: actions/upload-artifact@v4
              with:
                  name: digests-${{ inputs.cache_id }}-${{ env.PLATFORM_PAIR }}
                  path: /tmp/digests/*
                  if-no-files-found: error
                  retention-days: 1

The same workflow, on Latchkey

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

name: Build Docker Image
 
on:
    workflow_call:
        inputs:
            build_args:
                required: false
                default: ""
                type: string
            cache_id:
                required: true
                type: string
            extract_flavor:
                required: false
                default: ""
                type: string
            image_name:
                required: true
                type: string
            image_tag:
                required: false
                default: ""
                type: string
            registry:
                required: false
                default: ghcr.io
                type: string
 
env:
    FULL_IMAGE_NAME: ${{ inputs.registry }}/${{ inputs.image_name }}
 
jobs:
    build-image:
        timeout-minutes: 30
        runs-on: latchkey-small
        permissions:
            contents: read
            packages: write
        strategy:
            fail-fast: false
            matrix:
                platform:
                    - linux/amd64
                    - linux/arm64
 
        steps:
            - name: Prepare
              run: |
                  platform=${{ matrix.platform }}
                  echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
 
            - name: Checkout repository
              uses: actions/checkout@v4
 
            - name: Set up QEMU
              uses: docker/setup-qemu-action@v3
 
            - name: Set up Docker Buildx
              uses: docker/setup-buildx-action@v3
 
            - name: Log in to the Container registry
              uses: docker/login-action@v3
              with:
                  registry: ${{ inputs.registry }}
                  username: ${{ github.actor }}
                  password: ${{ secrets.GITHUB_TOKEN }}
 
            - name: Extract metadata for Docker images
              id: meta
              uses: docker/metadata-action@v5
              with:
                  images: ${{ env.FULL_IMAGE_NAME }}
                  tags: |
                      type=ref,event=branch
                      type=ref,event=tag
                      type=sha,prefix=git-
                      type=semver,pattern={{version}}
                      type=semver,pattern={{major}}.{{minor}}
                      ${{ inputs.image_tag }}
                  flavor: |
                      latest=${{ github.ref == 'refs/heads/main' }}
                      ${{ inputs.extract_flavor }}
 
            - name: Extract metadata for Docker cache
              id: cache-meta
              uses: docker/metadata-action@v5
              with:
                  images: ${{ env.FULL_IMAGE_NAME }}
                  tags: |
                      type=ref,event=branch
                  flavor: |
                      prefix=cache-${{ inputs.cache_id }}-${{ matrix.platform }}-
 
            - name: Build Docker image
              uses: docker/build-push-action@v5
              id: build
              with:
                  context: .
                  push: true
                  platforms: ${{ matrix.platform }}
                  labels: ${{ steps.meta.outputs.labels }}
                  outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
                  cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }}
                  cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max
                  build-args: |
                      BUILD_HASH=${{ github.sha }}
                      ${{ inputs.build_args }}
 
            - name: Export digest
              run: |
                  mkdir -p /tmp/digests
                  digest="${{ steps.build.outputs.digest }}"
                  touch "/tmp/digests/${digest#sha256:}"
 
            - name: Upload digest
              uses: actions/upload-artifact@v4
              with:
                  name: digests-${{ inputs.cache_id }}-${{ env.PLATFORM_PAIR }}
                  path: /tmp/digests/*
                  if-no-files-found: error
                  retention-days: 1
 

What changed

5 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 (2 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow