Move to Gitea: Gitea Actions workflow (BlueBuild CLI), registry git.lazypugs.com
bluebuild / Build Custom Image (push) Has been cancelled
bluebuild / Build Custom Image (push) Has been cancelled
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
# main-desktop
|
||||
|
||||
Custom [Bazzite DX](https://github.com/ublue-os/bazzite-dx) image for my desktop, built with
|
||||
[BlueBuild](https://blue-build.org), published to GHCR by GitHub Actions, and signed with cosign.
|
||||
[BlueBuild](https://blue-build.org), published to the container registry on my Gitea instance
|
||||
(**git.lazypugs.com**) by Gitea Actions, and signed with cosign.
|
||||
|
||||
- **Base:** `ghcr.io/ublue-os/bazzite-dx-nvidia` — Bazzite DX, KDE Plasma, **NVIDIA open kernel
|
||||
modules**. There is no separate `-open` DX image anymore: DX NVIDIA is open-driver-only, which
|
||||
@@ -20,29 +21,35 @@ in-image, the whole custom layer is "install these Flatpaks on first boot + trus
|
||||
which the `default-flatpaks` and `signing` modules express declaratively in ~40 lines of YAML —
|
||||
no hand-rolled first-boot systemd unit needed.
|
||||
|
||||
## One-time setup (before first push)
|
||||
## CI setup (Gitea Actions)
|
||||
|
||||
1. Create a GitHub repo and push this directory to it (`main` branch).
|
||||
2. Generate the signing keypair in the repo root (**press Enter for an empty password** — the
|
||||
build action cannot use an encrypted key):
|
||||
The workflow lives at [.gitea/workflows/build.yml](.gitea/workflows/build.yml) and runs the
|
||||
**BlueBuild CLI** directly (the `blue-build/github-action` is GitHub-only). It builds on push,
|
||||
manual dispatch, and daily at 06:00 UTC so base-image updates flow through automatically — that
|
||||
schedule is what makes the image self-updating.
|
||||
|
||||
```bash
|
||||
cosign generate-key-pair
|
||||
```
|
||||
Repo secrets (already configured):
|
||||
|
||||
3. Store the private key as an Actions secret and commit only the public half:
|
||||
- `SIGNING_SECRET` — contents of `cosign.key` (generated with an empty password; the public half
|
||||
is committed as `cosign.pub`). The CLI signs automatically on push when both are present.
|
||||
- `REGISTRY_TOKEN` — a Gitea personal access token with **write:package** scope, used to push to
|
||||
the registry. Gitea's automatic per-job token *cannot* publish packages (documented Gitea
|
||||
limitation), hence the PAT. **Currently seeded with a temporary token — before revoking it,
|
||||
create a durable PAT (Settings → Applications → Generate token, `write:package`) and update
|
||||
the secret** (repo Settings → Actions → Secrets, or
|
||||
`PUT /api/v1/repos/ckoch/main-desktop/actions/secrets/REGISTRY_TOKEN`).
|
||||
|
||||
```bash
|
||||
gh secret set SIGNING_SECRET < cosign.key
|
||||
git add cosign.pub && git commit -m "Add cosign public key" && git push
|
||||
```
|
||||
Runner requirements (act_runner on the instance):
|
||||
|
||||
`cosign.key` is git-ignored — never commit it.
|
||||
4. The workflow (`.github/workflows/build.yml`) now builds on every push, on manual dispatch, and
|
||||
daily at 06:00 UTC (so base-image updates flow through automatically — this is what makes the
|
||||
image self-updating). Images publish to `ghcr.io/<your-github-user>/main-desktop`.
|
||||
5. If the GHCR package ends up private, make it public in the package settings (Packages →
|
||||
main-desktop → Package settings → Change visibility), or rebasing will fail to pull.
|
||||
- **Privileged job containers must be allowed** — the build runs buildah inside the job
|
||||
container (`ghcr.io/blue-build/cli`). In the runner's `config.yaml`:
|
||||
`container: { privileged: true }`. Without it the build fails at the buildah stage.
|
||||
- Internet access (pulls the multi-GB Bazzite base from ghcr.io) and ~25+ GB free scratch disk.
|
||||
|
||||
Known first-run watch-items (verified docs, but no public precedent for this exact stack):
|
||||
cosign signature push to a Gitea registry and the CLI's tag generation under act_runner's
|
||||
GitHub-compat env are both expected to work but unproven in the wild — if the first run fails
|
||||
at signing or tagging, that's where to look, not the recipe.
|
||||
|
||||
## Rebasing the desktop onto this image
|
||||
|
||||
@@ -51,11 +58,11 @@ which contains the signing policy and public key), then signed:
|
||||
|
||||
```bash
|
||||
# Step 1: unsigned rebase, then reboot
|
||||
rpm-ostree rebase ostree-unverified-registry:ghcr.io/<your-github-user>/main-desktop:latest
|
||||
rpm-ostree rebase ostree-unverified-registry:git.lazypugs.com/ckoch/main-desktop:latest
|
||||
systemctl reboot
|
||||
|
||||
# Step 2: switch to the signed ref, then reboot
|
||||
rpm-ostree rebase ostree-image-signed:docker://ghcr.io/<your-github-user>/main-desktop:latest
|
||||
rpm-ostree rebase ostree-image-signed:docker://git.lazypugs.com/ckoch/main-desktop:latest
|
||||
systemctl reboot
|
||||
```
|
||||
|
||||
@@ -64,6 +71,14 @@ in the recipe, so `latest` never crosses a major until the recipe says so.
|
||||
|
||||
Roll back anytime with `rpm-ostree rollback` (or pick the previous deployment in the boot menu).
|
||||
|
||||
Notes for a self-hosted registry:
|
||||
|
||||
- The repo/package is public, so anonymous pulls work and the desktop needs no auth config. If
|
||||
you ever make it private, the *host* needs credentials in `/etc/ostree/auth.json`
|
||||
(containers-auth.json format) — `podman login` alone does not cover OS updates.
|
||||
- Updates only flow while git.lazypugs.com is reachable; if the box is down, updates pause and
|
||||
retry later. The running system is unaffected.
|
||||
|
||||
## Install-time checklist
|
||||
|
||||
1. **Driver sanity:** `nvidia-smi` reports driver **≥ 580** (currently 610.x) and the RTX 5090 is
|
||||
@@ -72,11 +87,11 @@ Roll back anytime with `rpm-ostree rollback` (or pick the previous deployment in
|
||||
2. **Signature:** verify the published image against the committed public key:
|
||||
|
||||
```bash
|
||||
cosign verify --key cosign.pub ghcr.io/<your-github-user>/main-desktop:latest
|
||||
cosign verify --key cosign.pub git.lazypugs.com/ckoch/main-desktop:latest
|
||||
```
|
||||
|
||||
3. **Deployment:** `rpm-ostree status` shows the booted deployment is
|
||||
`ostree-image-signed:docker://ghcr.io/<your-github-user>/main-desktop` and the base version
|
||||
`ostree-image-signed:docker://git.lazypugs.com/ckoch/main-desktop` and the base version
|
||||
matches a recent build.
|
||||
4. **Flatpaks:** the first-boot service installs the whole list below; give it a few minutes on
|
||||
first login (it notifies when done). Check with `flatpak list --system`.
|
||||
@@ -181,5 +196,8 @@ no local hypervisor tooling in this image.
|
||||
machine; `flatpak uninstall` it once by hand.)
|
||||
- **Jump Fedora majors:** change `image-version: stable-44` → `stable-45` in the recipe when
|
||||
ready, push, then update normally.
|
||||
- **Check build status:** the Actions tab; builds also run nightly, so a broken base shows up
|
||||
there before it reaches the machine.
|
||||
- **Check build status:** the repo's Actions tab; builds also run nightly, so a broken base
|
||||
shows up there before it reaches the machine.
|
||||
- **Key hygiene:** `cosign.key` is git-ignored and lives only on the workstation + in the
|
||||
`SIGNING_SECRET` secret — keep a backup (password manager). Losing it means generating a new
|
||||
pair, updating the secret, and re-doing the two-step rebase to re-establish trust.
|
||||
|
||||
Reference in New Issue
Block a user