diff --git a/.github/workflows/images.yml b/.github/workflows/images.yml index b612c71..84f4708 100644 --- a/.github/workflows/images.yml +++ b/.github/workflows/images.yml @@ -1,7 +1,12 @@ name: Build example runner images -# This repo ships EXAMPLE runners: images publish as /runner-example-. -# Production runners drop "example" (runner-). +# This repo ships EXAMPLE runners: images publish to the GitHub Container Registry +# as ghcr.io//runner-example-. Production runners drop "example" +# (runner-). +# +# GHCR needs no stored credentials: the built-in GITHUB_TOKEN publishes, and the +# packages are public, so pulling needs none either. Docker Hub is deliberately not +# a second target — see "Images" in the README. # # Runs on main / v* tags / manual dispatch; PRs build only (workflow_dispatch to # pull-test a branch). amd64 only (Livepeer GPU work is NVIDIA/amd64; no CUDA on @@ -32,6 +37,7 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + packages: write # publishing to ghcr.io strategy: fail-fast: false matrix: @@ -43,8 +49,8 @@ jobs: id: meta uses: docker/metadata-action@v6 with: - # Namespace defaults to livepeer; override via repo variable DOCKERHUB_NAMESPACE. - images: ${{ vars.DOCKERHUB_NAMESPACE || 'livepeer' }}/runner-example-${{ matrix.example }} + # Owner comes from the repo, so a fork publishes under its own namespace. + images: ghcr.io/${{ github.repository_owner }}/runner-example-${{ matrix.example }} tags: | type=raw,value=latest,enable={{is_default_branch}} type=sha,format=short @@ -60,13 +66,14 @@ jobs: uses: docker/setup-buildx-action@v4 # Allowlist push + dispatch — any other event (PRs, incl. pull_request_target) - # is build-only and never touches the Docker Hub secret. - - name: Log in to Docker Hub + # is build-only and never gets a package-writing token. + - name: Log in to GHCR if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' uses: docker/login-action@v4 with: - username: ${{ secrets.CI_DOCKERHUB_USERNAME }} - password: ${{ secrets.CI_DOCKERHUB_TOKEN }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v7 diff --git a/README.md b/README.md index 981e0c3..15dfe26 100644 --- a/README.md +++ b/README.md @@ -127,10 +127,13 @@ The orchestrator and signer services are defined once at the repo root and pulle ### Images -Each example ships a `Dockerfile` and a `compose.yml` that builds it locally. Those with a `Dockerfile` are also hosted on Docker Hub as `runner-example-` (`linux/amd64`), linked from the example's own README. Tags: `latest` (current `main`), `stable` (latest `v*` release), `1.2` / `1.2.3`, `sha-`. +Each example ships a `Dockerfile` and a `compose.yml` that builds it locally. Those with a `Dockerfile` are also published to the GitHub Container Registry as `ghcr.io/livepeer/runner-example-` (`linux/amd64`), linked from the example's own README. Tags: `latest` (current `main`), `stable` (latest `v*` release), `1.2` / `1.2.3`, `sha-`. -> [!NOTE] -> The images publish under `rickstaa/` until they move to the `livepeer` org ([#6](https://github.com/livepeer/runner-app-examples/issues/6)). +The packages are public, so no login is needed. `compose.yml` always builds; one flag runs the published image instead: + +```sh +docker compose up -d --pull always +``` ### On-chain (paid) setup diff --git a/echo/README.md b/echo/README.md index eeb8a38..0bb1e56 100644 --- a/echo/README.md +++ b/echo/README.md @@ -34,7 +34,7 @@ Two things follow from that, and they are what this example exists to show: ## Run offchain (free) > [!TIP] -> Built locally by the compose file below, and hosted at [`rickstaa/runner-example-echo`](https://hub.docker.com/r/rickstaa/runner-example-echo) — tags in the [repo README](../README.md#images). +> Built locally by the compose file below, or run the published [`ghcr.io/livepeer/runner-example-echo`](https://github.com/livepeer/runner-app-examples/pkgs/container/runner-example-echo) with `docker compose up -d --pull always` — see [Images](../README.md#images). Start the stack and confirm the runner registered: diff --git a/echo/compose.yml b/echo/compose.yml index cdaa6ef..4e52d6f 100644 --- a/echo/compose.yml +++ b/echo/compose.yml @@ -13,6 +13,9 @@ services: service: orchestrator app: + # `up` always builds; `--pull always` runs the published image instead. + image: ghcr.io/livepeer/runner-example-echo:latest + pull_policy: build build: . container_name: example_apps_echo # Wait for the orchestrator's healthcheck so registration doesn't race its boot. diff --git a/hello-world/README.md b/hello-world/README.md index 48ccb5c..ec9844d 100644 --- a/hello-world/README.md +++ b/hello-world/README.md @@ -20,7 +20,7 @@ The app is **dynamically registered**: it self-registers with the orchestrator v ## Run offchain (free) > [!TIP] -> Built locally by the compose file below, and hosted at [`rickstaa/runner-example-hello-world`](https://hub.docker.com/r/rickstaa/runner-example-hello-world) — tags in the [repo README](../README.md#images). +> Built locally by the compose file below, or run the published [`ghcr.io/livepeer/runner-example-hello-world`](https://github.com/livepeer/runner-app-examples/pkgs/container/runner-example-hello-world) with `docker compose up -d --pull always` — see [Images](../README.md#images). ```sh docker compose up -d --build diff --git a/hello-world/compose.yml b/hello-world/compose.yml index ed3af56..7297874 100644 --- a/hello-world/compose.yml +++ b/hello-world/compose.yml @@ -13,6 +13,9 @@ services: service: orchestrator app: + # `up` always builds; `--pull always` runs the published image instead. + image: ghcr.io/livepeer/runner-example-hello-world:latest + pull_policy: build build: . container_name: example_apps_hello_world # Wait for the orchestrator's healthcheck so registration doesn't race its boot. diff --git a/realtime-transcription/README.md b/realtime-transcription/README.md index 5f04b73..349034e 100644 --- a/realtime-transcription/README.md +++ b/realtime-transcription/README.md @@ -61,7 +61,7 @@ ffmpeg -f alsa -i default -ar 16000 -ac 1 -f s16le - \ ## Run offchain (free) > [!TIP] -> Built locally by the compose file below, and hosted at [`rickstaa/runner-example-realtime-transcription`](https://hub.docker.com/r/rickstaa/runner-example-realtime-transcription) — tags in the [repo README](../README.md#images). +> Built locally by the compose file below, or run the published [`ghcr.io/livepeer/runner-example-realtime-transcription`](https://github.com/livepeer/runner-app-examples/pkgs/container/runner-example-realtime-transcription) with `docker compose up -d --pull always` — see [Images](../README.md#images). ```sh docker compose up -d --build # first run downloads the whisper model diff --git a/realtime-transcription/compose.yml b/realtime-transcription/compose.yml index d8a1763..a7030e3 100644 --- a/realtime-transcription/compose.yml +++ b/realtime-transcription/compose.yml @@ -14,6 +14,9 @@ services: service: orchestrator app: + # `up` always builds; `--pull always` runs the published image instead. + image: ghcr.io/livepeer/runner-example-realtime-transcription:latest + pull_policy: build build: . container_name: example_apps_realtime_transcription # Wait for the orchestrator's healthcheck so registration doesn't race its boot. diff --git a/tiles/README.md b/tiles/README.md index a22d690..accb94c 100644 --- a/tiles/README.md +++ b/tiles/README.md @@ -34,7 +34,7 @@ The output image is identical either way. **Capacity changes throughput, not the ## Run offchain (free) > [!TIP] -> Built locally by the compose file below, and hosted at [`rickstaa/runner-example-tiles`](https://hub.docker.com/r/rickstaa/runner-example-tiles) — tags in the [repo README](../README.md#images). +> Built locally by the compose file below, or run the published [`ghcr.io/livepeer/runner-example-tiles`](https://github.com/livepeer/runner-app-examples/pkgs/container/runner-example-tiles) with `docker compose up -d --pull always` — see [Images](../README.md#images). ```sh CAPACITY=1 docker compose up -d --build diff --git a/tiles/compose.yml b/tiles/compose.yml index 519753b..bae6b7f 100644 --- a/tiles/compose.yml +++ b/tiles/compose.yml @@ -15,6 +15,9 @@ services: service: orchestrator app: + # `up` always builds; `--pull always` runs the published image instead. + image: ghcr.io/livepeer/runner-example-tiles:latest + pull_policy: build build: . container_name: example_apps_tiles # Wait for the orchestrator's healthcheck so registration doesn't race its boot.