|
|
@@ -1,8 +1,9 @@
|
|
|
|
# main-desktop
|
|
|
|
# main-desktop
|
|
|
|
|
|
|
|
|
|
|
|
Custom [Bazzite DX](https://github.com/ublue-os/bazzite-dx) image for my desktop, built with
|
|
|
|
Custom [Bazzite DX](https://github.com/ublue-os/bazzite-dx) image for my desktop, built with
|
|
|
|
[BlueBuild](https://blue-build.org), published to the container registry on my Gitea instance
|
|
|
|
[BlueBuild](https://blue-build.org), published signed (cosign) to the container registry on my
|
|
|
|
(**git.lazypugs.com**) by Gitea Actions, and signed with cosign.
|
|
|
|
Gitea instance (**git.lazypugs.com**) — built locally today, Gitea Actions-ready when a runner
|
|
|
|
|
|
|
|
is registered.
|
|
|
|
|
|
|
|
|
|
|
|
- **Base:** `ghcr.io/ublue-os/bazzite-dx-nvidia` — Bazzite DX, KDE Plasma, **NVIDIA open kernel
|
|
|
|
- **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
|
|
|
|
modules**. There is no separate `-open` DX image anymore: DX NVIDIA is open-driver-only, which
|
|
|
@@ -21,12 +22,37 @@ 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 —
|
|
|
|
which the `default-flatpaks` and `signing` modules express declaratively in ~40 lines of YAML —
|
|
|
|
no hand-rolled first-boot systemd unit needed.
|
|
|
|
no hand-rolled first-boot systemd unit needed.
|
|
|
|
|
|
|
|
|
|
|
|
## CI setup (Gitea Actions)
|
|
|
|
## Building & publishing
|
|
|
|
|
|
|
|
|
|
|
|
The workflow lives at [.gitea/workflows/build.yml](.gitea/workflows/build.yml) and runs the
|
|
|
|
### Locally (current path)
|
|
|
|
**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
|
|
|
|
The image is built and pushed from a workstation with the BlueBuild CLI driving Docker. From
|
|
|
|
schedule is what makes the image self-updating.
|
|
|
|
the repo root (needs `cosign.key` present there, and ~25 GB free for layers):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
# One-time CLI install (extracts a static binary to /usr/local/bin/bluebuild):
|
|
|
|
|
|
|
|
docker run --pull always --rm ghcr.io/blue-build/cli:latest-installer | bash
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Build, push, and sign in one shot:
|
|
|
|
|
|
|
|
BB_USERNAME=ckoch BB_PASSWORD=<gitea-PAT-with-write:package> \
|
|
|
|
|
|
|
|
bluebuild build --push --retry-push \
|
|
|
|
|
|
|
|
--registry git.lazypugs.com --registry-namespace ckoch \
|
|
|
|
|
|
|
|
recipes/recipe.yml
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tags are pinned in the recipe (`alt-tags: latest, stable-44`), so the pushed refs are the same
|
|
|
|
|
|
|
|
no matter where the build runs. Signing happens automatically because `cosign.pub` is in the
|
|
|
|
|
|
|
|
repo root and the key is available. **Rebuild cadence is manual under this model** — run the
|
|
|
|
|
|
|
|
build when you want base-image updates rolled in; the OS then picks them up on its normal
|
|
|
|
|
|
|
|
update timer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Gitea Actions (optional, needs a runner)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[.gitea/workflows/build.yml](.gitea/workflows/build.yml) runs the same **BlueBuild CLI** build
|
|
|
|
|
|
|
|
(the `blue-build/github-action` is GitHub-only). It is currently `workflow_dispatch`-only
|
|
|
|
|
|
|
|
because no Actions runner is registered on the instance; when one exists, restore the
|
|
|
|
|
|
|
|
commented-out `schedule` + `push` triggers in the workflow to make builds fully automatic
|
|
|
|
|
|
|
|
(daily rebuilds = true self-updating).
|
|
|
|
|
|
|
|
|
|
|
|
Repo secrets (already configured):
|
|
|
|
Repo secrets (already configured):
|
|
|
|
|
|
|
|
|
|
|
@@ -39,18 +65,13 @@ Repo secrets (already configured):
|
|
|
|
the secret** (repo Settings → Actions → Secrets, or
|
|
|
|
the secret** (repo Settings → Actions → Secrets, or
|
|
|
|
`PUT /api/v1/repos/ckoch/main-desktop/actions/secrets/REGISTRY_TOKEN`).
|
|
|
|
`PUT /api/v1/repos/ckoch/main-desktop/actions/secrets/REGISTRY_TOKEN`).
|
|
|
|
|
|
|
|
|
|
|
|
Runner requirements (act_runner on the instance):
|
|
|
|
Runner requirements when you set one up (act_runner):
|
|
|
|
|
|
|
|
|
|
|
|
- **Privileged job containers must be allowed** — the build runs buildah inside the job
|
|
|
|
- **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 (`ghcr.io/blue-build/cli`). In the runner's `config.yaml`:
|
|
|
|
`container: { privileged: true }`. Without it the build fails at the buildah stage.
|
|
|
|
`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.
|
|
|
|
- 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
|
|
|
|
## Rebasing the desktop onto this image
|
|
|
|
|
|
|
|
|
|
|
|
From the existing Bazzite install, rebase in two steps — first unsigned (this installs the image,
|
|
|
|
From the existing Bazzite install, rebase in two steps — first unsigned (this installs the image,
|
|
|
@@ -192,12 +213,12 @@ no local hypervisor tooling in this image.
|
|
|
|
## Maintenance
|
|
|
|
## Maintenance
|
|
|
|
|
|
|
|
|
|
|
|
- **Change the Flatpak list / packages:** edit [recipes/recipe.yml](recipes/recipe.yml), push,
|
|
|
|
- **Change the Flatpak list / packages:** edit [recipes/recipe.yml](recipes/recipe.yml), push,
|
|
|
|
and the next update picks it up. (Removing an app from the list does not uninstall it from the
|
|
|
|
rebuild (see "Building & publishing"), and the next OS update picks it up. (Removing an app
|
|
|
|
machine; `flatpak uninstall` it once by hand.)
|
|
|
|
from the list does not uninstall it from the machine; `flatpak uninstall` it once by hand.)
|
|
|
|
- **Jump Fedora majors:** change `image-version: stable-44` → `stable-45` in the recipe when
|
|
|
|
- **Jump Fedora majors:** change `image-version: stable-44` → `stable-45` in the recipe when
|
|
|
|
ready, push, then update normally.
|
|
|
|
ready, rebuild, then update normally.
|
|
|
|
- **Check build status:** the repo's Actions tab; builds also run nightly, so a broken base
|
|
|
|
- **Pull in base-image updates:** just rebuild — the base tag is `stable-44`, so each rebuild
|
|
|
|
shows up there before it reaches the machine.
|
|
|
|
picks up the newest Bazzite build within Fedora 44.
|
|
|
|
- **Key hygiene:** `cosign.key` is git-ignored and lives only on the workstation + in the
|
|
|
|
- **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
|
|
|
|
`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.
|
|
|
|
pair, updating the secret, and re-doing the two-step rebase to re-establish trust.
|
|
|
|