Skip to content
Latchkey

Docker Sanity workflow (mpieniak01/Venom)

The Docker Sanity workflow from mpieniak01/Venom, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get run de-duplication, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: mpieniak01/Venom.github/workflows/docker-sanity.ymlLicense MITView source

What it does

This is the Docker Sanity workflow from the mpieniak01/Venom 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: Docker Sanity

on:
  pull_request:
    branches: [main]
    paths:
      - "docker/**"
      - "compose/**"
      - "scripts/docker/**"
      - ".dockerignore"
      - ".github/workflows/docker-sanity.yml"
  workflow_dispatch:

permissions:
  contents: read

jobs:
  sanity:
    name: Validate Docker Minimal
    runs-on: ubuntu-latest
    timeout-minutes: 25

    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Validate compose file
        run: docker compose -f compose/compose.minimal.yml config > /dev/null

      - name: Validate shell scripts syntax
        run: |
          bash -n scripts/docker/install.sh
          bash -n scripts/docker/stack.sh
          bash -n scripts/docker/logs.sh
          bash -n scripts/docker/shell.sh

      - name: Build backend image
        run: docker build -f docker/backend.Dockerfile .

      - name: Build frontend image
        run: docker build -f docker/frontend.Dockerfile .

      - name: Smoke test (stack up + health endpoints)
        run: |
          set -euo pipefail
          trap 'echo "Smoke failed - dumping container status/logs"; docker compose -f compose/compose.minimal.yml ps; docker compose -f compose/compose.minimal.yml logs --tail=120 ollama backend frontend || true' ERR
          docker compose -f compose/compose.minimal.yml up -d --build

          wait_http() {
            local url="$1"
            local timeout="${2:-180}"
            local elapsed=0
            local interval=5

            until curl -fsS "$url" >/dev/null 2>&1; do
              sleep "$interval"
              elapsed=$((elapsed + interval))
              echo "Waiting for $url (${elapsed}s/${timeout}s)"
              if [[ "$elapsed" -ge "$timeout" ]]; then
                echo "Timeout for $url" >&2
                return 1
              fi
            done
          }

          wait_http "http://127.0.0.1:11434/api/tags" 180
          wait_http "http://127.0.0.1:8000/healthz" 240
          wait_http "http://127.0.0.1:3000" 240

      - name: Cleanup stack
        if: always()
        run: docker compose -f compose/compose.minimal.yml down --remove-orphans --volumes

The same workflow, on Latchkey

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

name: Docker Sanity
 
on:
  pull_request:
    branches: [main]
    paths:
      - "docker/**"
      - "compose/**"
      - "scripts/docker/**"
      - ".dockerignore"
      - ".github/workflows/docker-sanity.yml"
  workflow_dispatch:
 
permissions:
  contents: read
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  sanity:
    name: Validate Docker Minimal
    runs-on: latchkey-small
    timeout-minutes: 25
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5
 
      - name: Validate compose file
        run: docker compose -f compose/compose.minimal.yml config > /dev/null
 
      - name: Validate shell scripts syntax
        run: |
          bash -n scripts/docker/install.sh
          bash -n scripts/docker/stack.sh
          bash -n scripts/docker/logs.sh
          bash -n scripts/docker/shell.sh
 
      - name: Build backend image
        run: docker build -f docker/backend.Dockerfile .
 
      - name: Build frontend image
        run: docker build -f docker/frontend.Dockerfile .
 
      - name: Smoke test (stack up + health endpoints)
        run: |
          set -euo pipefail
          trap 'echo "Smoke failed - dumping container status/logs"; docker compose -f compose/compose.minimal.yml ps; docker compose -f compose/compose.minimal.yml logs --tail=120 ollama backend frontend || true' ERR
          docker compose -f compose/compose.minimal.yml up -d --build
 
          wait_http() {
            local url="$1"
            local timeout="${2:-180}"
            local elapsed=0
            local interval=5
 
            until curl -fsS "$url" >/dev/null 2>&1; do
              sleep "$interval"
              elapsed=$((elapsed + interval))
              echo "Waiting for $url (${elapsed}s/${timeout}s)"
              if [[ "$elapsed" -ge "$timeout" ]]; then
                echo "Timeout for $url" >&2
                return 1
              fi
            done
          }
 
          wait_http "http://127.0.0.1:11434/api/tags" 180
          wait_http "http://127.0.0.1:8000/healthz" 240
          wait_http "http://127.0.0.1:3000" 240
 
      - name: Cleanup stack
        if: always()
        run: docker compose -f compose/compose.minimal.yml down --remove-orphans --volumes
 

What changed

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