Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ name: build
# layer cache (an image this size would blow the 10 GB Actions cache anyway), and does
# not run on pull requests, where a build this size buys little for what it costs.
#
# GHCR needs no setup (ghcr.io/<owner>/<repo>, public if the repo is). Docker Hub
# is optional and additive: set the DOCKERHUB_NAMESPACE variable plus the
# DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets.
# GHCR needs no stored credentials: the built-in GITHUB_TOKEN publishes, and the
# package is public, so pulling needs none either. Docker Hub is deliberately not
# a second target: livepeer/ there is a curated product namespace, and this is an
# example.

on:
push:
Expand Down Expand Up @@ -48,16 +49,21 @@ jobs:
id: meta
uses: docker/metadata-action@v6
with:
# Second line is empty unless Docker Hub is configured, and empty
# entries are ignored, so this is GHCR-only by default.
images: |
ghcr.io/${{ github.repository }}
${{ vars.DOCKERHUB_NAMESPACE && format('{0}/{1}', vars.DOCKERHUB_NAMESPACE, github.event.repository.name) || '' }}
# Owner comes from the repo, so a fork publishes under its own namespace.
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,format=short
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=stable,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
# Set here rather than as Dockerfile LABELs: these are passed as --label,
# which wins over anything baked in, so one source of truth. The licence
# is the payload's (Apache-2.0) plus this wrapper's (MIT).
labels: |
org.opencontainers.image.title=streamdiffusion-livepeer-runner
org.opencontainers.image.description=daydream's StreamDiffusion, packaged to run on the Livepeer live runner; example, not production-ready
org.opencontainers.image.licenses=Apache-2.0 AND MIT

- name: Set up Buildx
uses: docker/setup-buildx-action@v4
Expand All @@ -69,13 +75,6 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Log in to Docker Hub
if: vars.DOCKERHUB_NAMESPACE != ''
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v7
with:
Expand Down
5 changes: 0 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
# and the driver arrives through the container runtime.
FROM python:3.11-slim

LABEL org.opencontainers.image.title="streamdiffusion-livepeer-runner"
LABEL org.opencontainers.image.description="daydream's StreamDiffusion realtime-img2img server, packaged unmodified to run as a Livepeer live runner"
LABEL org.opencontainers.image.source="https://github.com/livepeer/streamdiffusion-livepeer-runner"
LABEL org.opencontainers.image.licenses="Apache-2.0"

ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1
ENV HF_HUB_ENABLE_HF_TRANSFER=1

Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,15 @@ The price is unchanged by the overlay: static runners advertise it from `runners

## Ship it to an orchestrator

CI publishes the image to `ghcr.io/livepeer/streamdiffusion-livepeer-runner` on `main` and `v*` tags. An operator then runs it with a `runners.json` like this repo's, pointed at wherever they run the container, and needs no credentials for a public package.
CI publishes the image to `ghcr.io/livepeer/streamdiffusion-livepeer-runner` on `main` and `v*` tags. Tags: `latest` (current `main`), `stable` (latest `v*` release), `1.2` / `1.2.3`, `sha-<short>`. The package is public, so pulling needs no account and no login. An operator then runs it with a `runners.json` like this repo's, pointed at wherever they run the container.

The image is **~15 GB** (torch, TensorRT, ONNX Runtime), which is still close enough to what a GitHub-hosted runner has free that [build.yml](.github/workflows/build.yml) reclaims disk before building and skips the build on pull requests. Building locally is `docker compose build`.
`docker compose up` always builds from source. To run the published image instead, which is the sane path unless you are changing the Dockerfile:

To publish to Docker Hub as well, set the repository variable `DOCKERHUB_NAMESPACE` and the secrets `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN`. GHCR keeps working either way.
```sh
docker compose up -d --pull always
```

The image is **~15 GB** (torch, TensorRT, ONNX Runtime), which is still close enough to what a GitHub-hosted runner has free that [build.yml](.github/workflows/build.yml) reclaims disk before building and skips the build on pull requests. Building locally is `docker compose build`.

## Development

Expand Down
3 changes: 3 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ services:
start_period: 5s

app:
# `up` always builds; `--pull always` runs the published image instead.
image: ghcr.io/livepeer/streamdiffusion-livepeer-runner:latest
pull_policy: build
build: .
container_name: streamdiffusion_runner_app
# StreamDiffusion needs a GPU; compiled engines + the HF cache live in ./models
Expand Down
Loading