Docker workflow (pgrok/pgrok)
The Docker workflow from pgrok/pgrok, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Docker workflow from the pgrok/pgrok 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
name: Docker
on:
push:
branches:
- main
pull_request:
paths:
- 'Dockerfile'
- 'docker/**'
- '.github/workflows/docker.yml'
release:
types: [ published ]
jobs:
buildx:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'pgrok/pgrok' }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
runs-on: ubuntu-latest
permissions:
actions: write
contents: read
packages: write
steps:
- name: Check out code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Get latest tag
id: latest-tag
uses: WyriHaximus/github-action-get-previous-tag@04e8485ecb6487243907e330d522ff60f02283ce # v1
- name: Compute short commit SHA
id: short-sha
uses: benjlevesque/short-sha@726c11b3a56efd7710e7019505b802f083c98dcb # v2.1
- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
with:
platforms: linux/amd64,linux/arm64,linux/arm/v7
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Inspect builder
run: |
echo "Name: ${{ steps.buildx.outputs.name }}"
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
echo "Status: ${{ steps.buildx.outputs.status }}"
echo "Flags: ${{ steps.buildx.outputs.flags }}"
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
- name: Login to GitHub Container registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push images
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
build-args: |
BUILD_VERSION=${{ steps.latest-tag.outputs.tag }}+main.${{ steps.short-sha.outputs.sha }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: |
ghcr.io/pgrok/pgrokd:insiders
- name: Scan for container vulnerabilities
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0
with:
image-ref: ghcr.io/pgrok/pgrokd:insiders
exit-code: '1'
- name: Send email on failure
if: ${{ failure() }}
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
with:
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
buildx-pull-request:
if: ${{ github.event_name == 'pull_request'}}
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Check out code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Inspect builder
run: |
echo "Name: ${{ steps.buildx.outputs.name }}"
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
echo "Status: ${{ steps.buildx.outputs.status }}"
echo "Flags: ${{ steps.buildx.outputs.flags }}"
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
- name: Compute short commit SHA
id: short-sha
uses: benjlevesque/short-sha@726c11b3a56efd7710e7019505b802f083c98dcb # v2.1
- name: Build and push images
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
build-args: |
BUILD_VERSION=0.0.0-sha.${{ steps.short-sha.outputs.sha }}
platforms: linux/amd64
push: true
tags: |
ttl.sh/pgrok/pgrokd-${{ steps.short-sha.outputs.sha }}:1d
- name: Scan for container vulnerabilities
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0
with:
image-ref: ttl.sh/pgrok/pgrokd-${{ steps.short-sha.outputs.sha }}:1d
exit-code: '1'
# Updates to the following section needs to be synced to all release branches within their lifecycles.
buildx-release:
if: ${{ github.event_name == 'release' }}
runs-on: ubuntu-latest
permissions:
actions: write
contents: read
packages: write
steps:
- name: Compute image tag name
run: echo "IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)" >> $GITHUB_ENV
- name: Check out code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
with:
platforms: linux/amd64,linux/arm64,linux/arm/v7
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Inspect builder
run: |
echo "Name: ${{ steps.buildx.outputs.name }}"
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
echo "Status: ${{ steps.buildx.outputs.status }}"
echo "Flags: ${{ steps.buildx.outputs.flags }}"
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
- name: Login to GitHub Container registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push images
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
build-args: |
BUILD_VERSION=${{ env.IMAGE_TAG }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: |
ghcr.io/pgrok/pgrokd:${{ env.IMAGE_TAG }}
ghcr.io/pgrok/pgrokd:latest
- name: Send email on failure
if: ${{ failure() }}
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
with:
smtp_username: ${{ secrets.SMTP_USERNAME }}
smtp_password: ${{ secrets.SMTP_PASSWORD }}
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Docker on: push: branches: - main pull_request: paths: - 'Dockerfile' - 'docker/**' - '.github/workflows/docker.yml' release: types: [ published ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: buildx: timeout-minutes: 30 if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'pgrok/pgrok' }} concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true runs-on: latchkey-small permissions: actions: write contents: read packages: write steps: - name: Check out code uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 - name: Get latest tag id: latest-tag uses: WyriHaximus/github-action-get-previous-tag@04e8485ecb6487243907e330d522ff60f02283ce # v1 - name: Compute short commit SHA id: short-sha uses: benjlevesque/short-sha@726c11b3a56efd7710e7019505b802f083c98dcb # v2.1 - name: Set up QEMU uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 with: platforms: linux/amd64,linux/arm64,linux/arm/v7 - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Inspect builder run: | echo "Name: ${{ steps.buildx.outputs.name }}" echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}" echo "Status: ${{ steps.buildx.outputs.status }}" echo "Flags: ${{ steps.buildx.outputs.flags }}" echo "Platforms: ${{ steps.buildx.outputs.platforms }}" - name: Login to GitHub Container registry uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push images uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: . build-args: | BUILD_VERSION=${{ steps.latest-tag.outputs.tag }}+main.${{ steps.short-sha.outputs.sha }} platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: | ghcr.io/pgrok/pgrokd:insiders - name: Scan for container vulnerabilities uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 with: image-ref: ghcr.io/pgrok/pgrokd:insiders exit-code: '1' - name: Send email on failure if: ${{ failure() }} uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1 with: smtp_username: ${{ secrets.SMTP_USERNAME }} smtp_password: ${{ secrets.SMTP_PASSWORD }} buildx-pull-request: timeout-minutes: 30 if: ${{ github.event_name == 'pull_request'}} runs-on: latchkey-small permissions: contents: read steps: - name: Check out code uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Inspect builder run: | echo "Name: ${{ steps.buildx.outputs.name }}" echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}" echo "Status: ${{ steps.buildx.outputs.status }}" echo "Flags: ${{ steps.buildx.outputs.flags }}" echo "Platforms: ${{ steps.buildx.outputs.platforms }}" - name: Compute short commit SHA id: short-sha uses: benjlevesque/short-sha@726c11b3a56efd7710e7019505b802f083c98dcb # v2.1 - name: Build and push images uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: . build-args: | BUILD_VERSION=0.0.0-sha.${{ steps.short-sha.outputs.sha }} platforms: linux/amd64 push: true tags: | ttl.sh/pgrok/pgrokd-${{ steps.short-sha.outputs.sha }}:1d - name: Scan for container vulnerabilities uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 with: image-ref: ttl.sh/pgrok/pgrokd-${{ steps.short-sha.outputs.sha }}:1d exit-code: '1' # Updates to the following section needs to be synced to all release branches within their lifecycles. buildx-release: timeout-minutes: 30 if: ${{ github.event_name == 'release' }} runs-on: latchkey-small permissions: actions: write contents: read packages: write steps: - name: Compute image tag name run: echo "IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)" >> $GITHUB_ENV - name: Check out code uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Set up QEMU uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 with: platforms: linux/amd64,linux/arm64,linux/arm/v7 - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Inspect builder run: | echo "Name: ${{ steps.buildx.outputs.name }}" echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}" echo "Status: ${{ steps.buildx.outputs.status }}" echo "Flags: ${{ steps.buildx.outputs.flags }}" echo "Platforms: ${{ steps.buildx.outputs.platforms }}" - name: Login to GitHub Container registry uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push images uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: . build-args: | BUILD_VERSION=${{ env.IMAGE_TAG }} platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: | ghcr.io/pgrok/pgrokd:${{ env.IMAGE_TAG }} ghcr.io/pgrok/pgrokd:latest - name: Send email on failure if: ${{ failure() }} uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1 with: smtp_username: ${{ secrets.SMTP_USERNAME }} smtp_password: ${{ secrets.SMTP_PASSWORD }}
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Add a job timeout so a hung step cannot burn hours of runner time.
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:
- Container pulls and builds
This workflow runs 3 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.