Skip to content

Publish an image for every service Compose can build, on both architectures - #365

Merged
davidmckayv merged 1 commit into
mainfrom
images
Sep 4, 2026
Merged

Publish an image for every service Compose can build, on both architectures#365
davidmckayv merged 1 commit into
mainfrom
images

Conversation

@davidmckayv

@davidmckayv davidmckayv commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

P0 of the OpenBot Desktop build: publish the images instead of building them on the user's machine.

ghcr.io/copilotkit/openbot was the only image a release produced, so anything running the Compose stack built agent-computer, the supervisor, both Bots and the migration image from source on every machine. That needs a toolchain and several minutes, most of them Chromium.

What this does

  • Publishes each of those five at ghcr.io/copilotkit/openbot-<service>, linux/amd64 and linux/arm64, joined into one manifest list, each with its own build provenance attestation.
  • Records a digest for every one of them in the release's container-images.json, and refuses to write the file if any is missing.
  • Adds SUPERVISOR_IMAGE, BOT_IMAGE, LANGGRAPH_IMAGE and SERVER_IMAGE alongside the existing COMPUTER_IMAGE, plus IMAGE_PULL_POLICY, so a machine can pull those digests rather than build.
  • Builds the five Dockerfiles in CI. Nothing did before.

Native arm64 runners rather than QEMU: emulated bun install and vite build are a known source of release-day flakiness, and arm64 runners cost a public repository nothing, so emulation would be slower and less reliable at no saving.

Why CI now builds them

They are built by docker compose up --build, which only the smoke journey runs and which cannot run in CI. So a broken supervisor/Dockerfile surfaced during a release, after the openbot image had already been pushed, which docs/releasing.md already calls out as the one failure that leaves a published image with nothing pointing at it.

.github/published-images.json is the single list, read by the publishing matrix and by CI, and CI fails if it stops matching the Dockerfiles in the tree. A Dockerfile the release does not publish is one a machine would build from source, and that failure is otherwise silent.

Verified

  • component dockerfiles and image both pass on this PR. The full-ci label did not exist in this repository until now, so the image job had never once run on a pull request despite being gated on that label since it was written.
  • All five build on linux/arm64, locally. Nothing had ever built them for arm64; every base image (Playwright noble, oven/bun, spire-server) does publish it.
  • The merge mechanism, end to end against a throwaway local registry: two per-arch pushes by digest, imagetools create into a tagged manifest list, both platforms present, both attestation manifests carried through with correct vnd.docker.reference.digest back-references, and docker pull --platform working for each from the merged tag.
  • imagetools inspect --format '{{.Manifest.Digest}}' returns the list digest, checked against the raw manifest hash.
  • IMAGE_PULL_POLICY: unset builds, missing pulls. It also falls back to building when the pull fails, which the comment and the docs now say, because that is right for a developer and wrong for a machine with no toolchain, where the useful answer is that the image could not be fetched. Anything shipping these to a machine that cannot build overrides the build sections away instead.

Not verified

The publishing jobs themselves have not run: ubuntu-24.04-arm and the artifact hand-off between the matrix jobs are first exercised by the next release, which is also the first release whose container-images.json carries more than one image.

@davidmckayv davidmckayv added the full-ci Run the slow image builds on this PR label Sep 4, 2026
@davidmckayv
davidmckayv force-pushed the images branch 3 times, most recently from aeb4041 to c87cbda Compare September 4, 2026 17:57
…ctures

`ghcr.io/copilotkit/openbot` was the only image a release produced, so anything
running the Compose stack built `agent-computer`, the supervisor, both Bots and
the migration image from source on every machine: a toolchain, and several
minutes of Chromium.

Each is now published beside it at `ghcr.io/copilotkit/openbot-<service>`,
carrying `linux/amd64` and `linux/arm64` so one reference works on a server and
on an arm64 laptop. Built on native runners of each architecture and joined into
a manifest list, rather than under QEMU, because emulated `bun install` and
`vite build` are a known source of release-day flakiness and arm64 runners cost
a public repository nothing. Each list gets its own build provenance
attestation, and `container-images.json` pins a digest for all of them.

Nothing changes for a checkout: unset, `COMPUTER_IMAGE`, `SUPERVISOR_IMAGE`,
`BOT_IMAGE`, `LANGGRAPH_IMAGE` and `SERVER_IMAGE` name local tags and Compose
builds them as before. Point them at published digests and set
`IMAGE_PULL_POLICY=missing` to pull instead. That is deliberately not a promise
that nothing is built, and the comment says so: a failed pull falls back to
building, which suits a developer and not a machine without a toolchain.

`.github/published-images.json` is the list, read by the publishing matrix and
by CI, which now builds those five Dockerfiles and fails if the list stops
matching the tree. Nothing built them before, because they are built by
`docker compose up --build`, which only the smoke journey runs and which cannot
run in CI, so a broken one surfaced during a release after the first image had
already been pushed.
@davidmckayv
davidmckayv merged commit ff00ada into main Sep 4, 2026
15 checks passed
@davidmckayv
davidmckayv deleted the images branch September 4, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-ci Run the slow image builds on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant