Compare commits
4
Commits
7f0a30c01f
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf3fc8bb79 | ||
|
|
5ea3384880 | ||
|
|
73d92a6e7d | ||
|
|
2d392f9d69 |
@@ -1,42 +0,0 @@
|
|||||||
# Gitea Actions workflow. Uses the BlueBuild CLI directly — the blue-build/github-action
|
|
||||||
# is a GitHub-context composite and is not supported outside GitHub/GitLab CI.
|
|
||||||
# Runner requirement: act_runner must allow privileged job containers
|
|
||||||
# (container.privileged: true in the runner's config.yaml) — buildah needs it.
|
|
||||||
# NOTE: manual-only for now — no Actions runner is registered on the instance, and the
|
|
||||||
# image is currently built/pushed locally (see README "Building locally"). When a runner
|
|
||||||
# exists, restore the schedule + push triggers below to make builds fully automatic:
|
|
||||||
# schedule:
|
|
||||||
# - cron: "00 06 * * *" # daily rebuild pulls in base-image updates
|
|
||||||
# push:
|
|
||||||
# branches: [main]
|
|
||||||
# paths-ignore: ["**.md"]
|
|
||||||
name: bluebuild
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
bluebuild:
|
|
||||||
name: Build Custom Image
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: ghcr.io/blue-build/cli:v0.9
|
|
||||||
options: --privileged
|
|
||||||
env:
|
|
||||||
# Auto-signs on push when this + cosign.pub (repo root) are present.
|
|
||||||
COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }}
|
|
||||||
# Gitea's auto job token cannot push packages (documented limitation),
|
|
||||||
# so registry auth uses a PAT with write:package scope.
|
|
||||||
BB_REGISTRY: git.lazypugs.com
|
|
||||||
BB_REGISTRY_NAMESPACE: ckoch
|
|
||||||
BB_USERNAME: ckoch
|
|
||||||
BB_PASSWORD: ${{ secrets.REGISTRY_TOKEN }}
|
|
||||||
steps:
|
|
||||||
# Plain clone instead of actions/checkout: the CLI job container isn't
|
|
||||||
# guaranteed to have node, and the repo is public.
|
|
||||||
- name: Clone repo
|
|
||||||
run: |
|
|
||||||
git config --global --add safe.directory "$(pwd)"
|
|
||||||
git clone --depth 1 --branch "${GITHUB_REF_NAME:-main}" "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" .
|
|
||||||
|
|
||||||
- name: Build and push signed image
|
|
||||||
run: bluebuild build --verbose --push --retry-push recipes/recipe.yml
|
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
# Development setup
|
||||||
|
|
||||||
|
What the 29 projects in `~/Documents/Development` need on the new machine, mapped against what
|
||||||
|
the image already provides. Scanned 2026-07 from each project's manifests, Dockerfiles, and
|
||||||
|
setup scripts. Run [scripts/dev-setup.sh](scripts/dev-setup.sh) after first boot to install the
|
||||||
|
toolchain layer in one shot.
|
||||||
|
|
||||||
|
## Already in the image — install nothing
|
||||||
|
|
||||||
|
| Need | Provided by | Used by |
|
||||||
|
|---|---|---|
|
||||||
|
| Docker CE + compose, Podman, skopeo | Bazzite DX base | requester, serverTransfer, ispy, keyWord, encoderPro, movieScanner, kidstube, Docker-Registry-Browser, smartSpeaker… |
|
||||||
|
| NVIDIA driver (610+ open) + container toolkit + CDI | base (nvidia image) | AIVoice, ispy, keyWord, encoderPro, smartSpeaker whisper, superBossMonster art pipeline |
|
||||||
|
| qemu/KVM + virt tooling | DX base | BC250 VM testing |
|
||||||
|
| android-tools (adb) | DX base | denon-bluetooth btsnoop captures |
|
||||||
|
| Steam + Proton | Bazzite base | BG4_UltraWide_fix |
|
||||||
|
| VS Code, git, Homebrew, just | DX base | everything |
|
||||||
|
| BlueZ/bluetoothd, rsync, openssh | Fedora base | denon-bluetooth, serverTransfer |
|
||||||
|
| Godot (current stable), Android Studio | first-boot Flatpaks | superBossMonster/FFCardGame, native-angular |
|
||||||
|
|
||||||
|
AIVoice's `SETUP.md` warning about snap Docker / Docker Desktop is moot here: Bazzite DX ships
|
||||||
|
native docker-ce, which is exactly what it wants. Its
|
||||||
|
`nvidia-ctk runtime configure --runtime=docker` step is the same one in the README's GPU
|
||||||
|
section.
|
||||||
|
|
||||||
|
## Toolchains — mise (all per-version needs found in the scan)
|
||||||
|
|
||||||
|
No project commits `.nvmrc`/`.python-version`/`.tool-versions`, so versions below come from
|
||||||
|
Dockerfiles and build configs. `dev-setup.sh` installs mise and these versions:
|
||||||
|
|
||||||
|
- **Node 22** global default (requester, movieScanner); projects also reference 18
|
||||||
|
(Docker-Registry-Browser, movieMetaTagger) and 20 (FFCardGame server, kidstube) — installed
|
||||||
|
side-by-side, pin per-project with `mise use node@18` in the project dir (writes
|
||||||
|
`mise.toml` — worth committing so this guesswork ends).
|
||||||
|
- **Python 3.12** (serverTransfer, movieMetaTagger, movieScanner, nameFixer4000, BG4 tools) and
|
||||||
|
**3.11** floor (FRScanner). Fedora 44's system python is newer — don't rely on it for these.
|
||||||
|
- **JDK 21** (villager-logic-fix, Minecraft-Village-Warriors release target), **JDK 17**
|
||||||
|
(native-angular android-host), **JDK 25** (Minecraft-Village-Warriors toolchain — Gradle can
|
||||||
|
also auto-provision it). Gradle itself always via each repo's wrapper.
|
||||||
|
- **.NET 10 SDK** (requester; also rebuilds the BG4 BepInEx plugin).
|
||||||
|
- **Go** and **Rust** — present on the old machine (`~/go`, `~/.cargo`); no scanned project pins
|
||||||
|
a version, so latest.
|
||||||
|
|
||||||
|
## Native builds — use a distrobox, not the host
|
||||||
|
|
||||||
|
Compilers and C library headers don't belong on the atomic host. One Fedora distrobox covers
|
||||||
|
every native-build need the scan found:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
distrobox create dev --image registry.fedoraproject.org/fedora:44
|
||||||
|
distrobox enter dev
|
||||||
|
sudo dnf install -y gcc gcc-c++ make cmake pkgconf python3-devel \
|
||||||
|
gtk4-devel \ # native-angular linux-host (CMake + GTK4)
|
||||||
|
zbar \ # DVDPhotoMatic (pyzbar)
|
||||||
|
libsndfile mediainfo-libs \ # FRScanner audio / movieMetaTagger pymediainfo
|
||||||
|
rtl-sdr rtl-sdr-devel \ # FRScanner RTL-SDR + Cython builds
|
||||||
|
mkvtoolnix ffmpeg-free \ # movieMetaTagger mkvpropedit; ffmpeg fallback
|
||||||
|
python3-tkinter python3-dbus \ # denon-bluetooth GUI
|
||||||
|
flashrom # BC250 BIOS flashing (CH347 over USB)
|
||||||
|
```
|
||||||
|
|
||||||
|
Native node modules (kidstube's better-sqlite3, FFCardGame's bcrypt) build fine inside the
|
||||||
|
distrobox too — or in their Docker builds, which is how they ship anyway.
|
||||||
|
|
||||||
|
## Host-level odds and ends
|
||||||
|
|
||||||
|
- **RTL-SDR udev rules** (FRScanner): the dongle permissions must live on the *host* —
|
||||||
|
`dev-setup.sh` writes `/etc/udev/rules.d/20-rtlsdr.rules` (`/etc` is mutable and survives
|
||||||
|
updates).
|
||||||
|
- **ffmpeg on the host** (audioSticher, AIVoice host venv, encoderPro host runs): Bazzite
|
||||||
|
ships ffmpeg — verify with `ffmpeg -version`; if a project needs full codecs beyond it,
|
||||||
|
`brew install ffmpeg` wins on PATH.
|
||||||
|
- **Pinned Godot binaries**: superBossMonster hardcodes `~/godot/Godot_v4.3-stable_linux.x86_64`
|
||||||
|
and FFCardGame ships its own 4.2 binary. Keep the `~/godot/` directory from the old machine
|
||||||
|
(plus export templates in `~/.local/share/godot/`); the Flatpak is only "current stable".
|
||||||
|
- **gh CLI**: `brew install gh` (in `dev-setup.sh`) — used across projects.
|
||||||
|
- **BlueBuild CLI** (BC250 and this repo): the installer one-liner in the README.
|
||||||
|
- **API keys**: ANTHROPIC_API_KEY (FFCardGame tools, DVDPhotoMatic), TMDB/OMDB
|
||||||
|
(movieScanner, nameFixer4000, DVDPhotoMatic), YouTube Data v3 (kidstube) — carried in
|
||||||
|
per-project `.env` files; bring them over with your home directory.
|
||||||
|
|
||||||
|
## Per-project cheat sheet
|
||||||
|
|
||||||
|
| Project | Needs beyond the image |
|
||||||
|
|---|---|
|
||||||
|
| AIVoice | py3.12 venv (mise), ffmpeg, GPU containers (covered) |
|
||||||
|
| AIVoices_HA, personal-landing, cardscraper, audioSticher, teamsTrick | nothing / stdlib python |
|
||||||
|
| BC250 | BlueBuild CLI, flashrom (distrobox) |
|
||||||
|
| BG4_UltraWide_fix | .NET 10, py3.12, Steam/Proton (covered) |
|
||||||
|
| denon-bluetooth | distrobox tkinter+dbus, adb (covered) |
|
||||||
|
| Docker-Registry-Browser | Node 18 |
|
||||||
|
| DVDPhotoMatic | finished project — py3.12, zbar (distrobox), webcam if ever revived; OpenSCAD flatpak for the jig files if needed |
|
||||||
|
| encoderPro, ispy, keyWord, movieScanner, nameFixer4000, serverTransfer | Docker (+GPU) only |
|
||||||
|
| FFCardGame | Godot 4.2 binary, Node 20, python+anthropic |
|
||||||
|
| FRScanner | py3.11+, rtl-sdr distrobox + host udev rules |
|
||||||
|
| kidstube | Node 20 (+distrobox for native build outside Docker) |
|
||||||
|
| Minecraft mods (×2) | JDK 21/25 via mise |
|
||||||
|
| movieMetaTagger | py3.12, Node 18, mkvtoolnix/mediainfo (distrobox) |
|
||||||
|
| native-angular | Node 20+, JDK 17, Android Studio (flatpak), GTK4 distrobox |
|
||||||
|
| requester | .NET 10, Node 22, postgres via compose |
|
||||||
|
| smartSpeaker | Docker (covered); Pi hardware is remote |
|
||||||
|
| superBossMonster | Godot 4.3 binary + templates, ComfyUI in GPU container |
|
||||||
|
| teamsTrick | X11 session note: KDE on Bazzite defaults to Wayland — run it in an X11 session or expect XTest to fail |
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
# 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, defined with
|
||||||
[BlueBuild](https://blue-build.org), published signed (cosign) to the container registry on my
|
[BlueBuild](https://blue-build.org). **There is no published image** — clone this repo and build
|
||||||
Gitea instance (**git.lazypugs.com**) — built locally today, Gitea Actions-ready when a runner
|
it yourself; `bluebuild switch` rebases the running system straight onto the local build.
|
||||||
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
|
||||||
@@ -14,110 +13,58 @@ is registered.
|
|||||||
- **This image layers almost nothing.** The base already includes Steam and the gaming stack,
|
- **This image layers almost nothing.** The base already includes Steam and the gaming stack,
|
||||||
Flatpak, Docker CE + CLI, Podman, VS Code, Homebrew, **and nvidia-container-toolkit with
|
Flatpak, Docker CE + CLI, Podman, VS Code, Homebrew, **and nvidia-container-toolkit with
|
||||||
automatic CDI setup** (`ublue-nvctk-cdi.service` regenerates `/etc/cdi/nvidia.yaml` each boot).
|
automatic CDI setup** (`ublue-nvctk-cdi.service` regenerates `/etc/cdi/nvidia.yaml` each boot).
|
||||||
What this recipe adds: the cosign signature-verification policy and a declarative first-boot
|
What this recipe adds: a declarative first-boot Flatpak set (and a dormant signing policy).
|
||||||
Flatpak set. That's it — by design.
|
That's it — by design.
|
||||||
|
|
||||||
Why BlueBuild instead of the raw Containerfile template: with the container toolkit already
|
Why BlueBuild instead of a raw Containerfile: the whole custom layer is "install these Flatpaks
|
||||||
in-image, the whole custom layer is "install these Flatpaks on first boot + trust my signature",
|
on first boot", which the `default-flatpaks` module expresses declaratively — and
|
||||||
which the `default-flatpaks` and `signing` modules express declaratively in ~40 lines of YAML —
|
`bluebuild switch` gives a one-command build-and-rebase with no registry involved.
|
||||||
no hand-rolled first-boot systemd unit needed.
|
|
||||||
|
|
||||||
## Building & publishing
|
## Getting onto this image (fresh desktop rebuild)
|
||||||
|
|
||||||
### Locally (current path)
|
1. Install stock **Bazzite DX (NVIDIA)** from the official ISO at
|
||||||
|
[bazzite.gg](https://bazzite.gg) and boot into it.
|
||||||
|
2. Install the BlueBuild CLI and switch:
|
||||||
|
|
||||||
The image is built and pushed from a workstation with the BlueBuild CLI driving Docker. From
|
```bash
|
||||||
the repo root (needs `cosign.key` present there, and ~25 GB free for layers):
|
git clone https://git.lazypugs.com/ckoch/main-desktop.git && cd main-desktop
|
||||||
|
podman run --pull always --rm ghcr.io/blue-build/cli:latest-installer | bash
|
||||||
|
bluebuild switch recipes/recipe.yml # add --reboot to reboot when done
|
||||||
|
```
|
||||||
|
|
||||||
|
`switch` builds the image locally, stores it as an oci-archive under `/etc/bluebuild/`, and
|
||||||
|
rebases `rpm-ostree` onto it. First build pulls the multi-GB base — give it time and disk
|
||||||
|
(~25 GB free).
|
||||||
|
3. Reboot. Done — the first-boot service then installs the Flatpak list below (needs a few
|
||||||
|
minutes on first login; check with `flatpak list --system`).
|
||||||
|
|
||||||
|
Alternatively, `bluebuild generate-iso recipes/recipe.yml` can produce installer media with the
|
||||||
|
custom image baked in, skipping step 1's stock install.
|
||||||
|
|
||||||
|
**Updating later** (pulls the newest Bazzite `stable-44` base plus any recipe changes):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# One-time CLI install (extracts a static binary to /usr/local/bin/bluebuild):
|
cd main-desktop && git pull && bluebuild update recipes/recipe.yml --reboot
|
||||||
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):
|
|
||||||
|
|
||||||
- `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`).
|
|
||||||
|
|
||||||
Runner requirements when you set one up (act_runner):
|
|
||||||
|
|
||||||
- **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.
|
|
||||||
|
|
||||||
## Rebasing the desktop onto this image
|
|
||||||
|
|
||||||
From the existing Bazzite install, rebase in two steps — first unsigned (this installs the image,
|
|
||||||
which contains the signing policy and public key), then signed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Step 1: unsigned rebase, then reboot
|
|
||||||
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://git.lazypugs.com/ckoch/main-desktop:latest
|
|
||||||
systemctl reboot
|
|
||||||
```
|
|
||||||
|
|
||||||
After step 2, every update is signature-verified. `:latest` is fine here — the Fedora pin lives
|
|
||||||
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).
|
Roll back anytime with `rpm-ostree rollback` (or pick the previous deployment in the boot menu).
|
||||||
|
|
||||||
Notes for a self-hosted registry:
|
Note on signing: local oci-archive rebases are inherently unsigned (`ostree-unverified-image`),
|
||||||
|
so cosign doesn't apply here. The recipe keeps the `signing` module and `cosign.pub` so that
|
||||||
- The repo/package is public, so anonymous pulls work and the desktop needs no auth config. If
|
publishing signed images to a registry later is just a `bluebuild build --push` away.
|
||||||
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
|
## Install-time checklist
|
||||||
|
|
||||||
1. **Driver sanity:** `nvidia-smi` reports driver **≥ 580** (currently 610.x) and the RTX 5090 is
|
1. **Driver sanity:** `nvidia-smi` reports driver **≥ 580** (currently 610.x) and the RTX 5090 is
|
||||||
listed. Confirm open kernel modules: `modinfo -F license nvidia` should say `Dual MIT/GPL`
|
listed. Confirm open kernel modules: `modinfo -F license nvidia` should say `Dual MIT/GPL`
|
||||||
(the proprietary module says `NVIDIA`). Blackwell only works on the open modules.
|
(the proprietary module says `NVIDIA`). Blackwell only works on the open modules.
|
||||||
2. **Signature:** verify the published image against the committed public key:
|
2. **Deployment:** `rpm-ostree status` shows the booted deployment is the local build
|
||||||
|
(`ostree-unverified-image:oci-archive:/etc/bluebuild/...`) with the expected base version.
|
||||||
```bash
|
3. **Flatpaks:** all installed (`flatpak list --system` — 22 apps from the list below). The
|
||||||
cosign verify --key cosign.pub git.lazypugs.com/ckoch/main-desktop:latest
|
first-boot install is sequential and multi-GB; on slow links it can take 15+ minutes after
|
||||||
```
|
first login. Progress: `journalctl -b --grep flatpak -f`.
|
||||||
|
4. **Docker group:** run `ujust dx-group` (adds you to `docker` and friends), then log out/in.
|
||||||
3. **Deployment:** `rpm-ostree status` shows the booted deployment is
|
5. **GPU in containers:** run the one-liner test in the next section.
|
||||||
`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`.
|
|
||||||
5. **Docker group:** run `ujust dx-group` (adds you to `docker` and friends), then log out/in.
|
|
||||||
6. **GPU in containers:** see the section below — run the one-liner test.
|
|
||||||
|
|
||||||
## GPU in containers (CUDA on the 5090)
|
## GPU in containers (CUDA on the 5090)
|
||||||
|
|
||||||
@@ -147,21 +94,30 @@ Flathub (2026-07).
|
|||||||
|
|
||||||
**Official / verified listings:** Bambu Studio, Bitwarden, Discord, Firefox, Thunderbird,
|
**Official / verified listings:** Bambu Studio, Bitwarden, Discord, Firefox, Thunderbird,
|
||||||
FreeCAD, GIMP, HandBrake, LibreOffice, Moonlight, PCSX2 (`net.pcsx2.PCSX2` — the official
|
FreeCAD, GIMP, HandBrake, LibreOffice, Moonlight, PCSX2 (`net.pcsx2.PCSX2` — the official
|
||||||
build), Podman Desktop, Warzone 2100, XIVLauncher (`dev.goats.xivlauncher`).
|
build), Podman Desktop, Prism Launcher, Warzone 2100, XIVLauncher (`dev.goats.xivlauncher`).
|
||||||
|
|
||||||
**Community / unverified listings — know what you're running:**
|
**Community / unverified listings — know what you're running:**
|
||||||
|
|
||||||
| App | ID | Note |
|
| App | ID | Note |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|
| Android Studio | `com.google.AndroidStudio` | Community packaging of Google's IDE (not verified) |
|
||||||
| GitHub Desktop | `io.github.shiftey.Desktop` | Community Linux fork; the "shiftey" spelling is the real ID |
|
| GitHub Desktop | `io.github.shiftey.Desktop` | Community Linux fork; the "shiftey" spelling is the real ID |
|
||||||
| MakeMKV | `com.makemkv.MakeMKV` | Community packaging of the proprietary app |
|
| MakeMKV | `com.makemkv.MakeMKV` | Community packaging of the proprietary app |
|
||||||
| GeForce NOW | `io.github.hmlendea.geforcenow-electron` | **Unofficial** Electron wrapper, not an NVIDIA product |
|
| GeForce NOW | `io.github.hmlendea.geforcenow-electron` | **Unofficial** Electron wrapper, not an NVIDIA product |
|
||||||
|
| Spotify | `com.spotify.Client` | Community packaging of the proprietary client |
|
||||||
| VLC | `org.videolan.VLC` | No verified badge on Flathub (still the VideoLAN-maintained build) |
|
| VLC | `org.videolan.VLC` | No verified badge on Flathub (still the VideoLAN-maintained build) |
|
||||||
| Godot | `org.godotengine.Godot` | No verified badge on Flathub |
|
| Godot | `org.godotengine.Godot` | No verified badge on Flathub |
|
||||||
|
|
||||||
**GeForce NOW on the 32:9 monitor:** the service only streams 16:9 (and some 21:9) aspect
|
**GeForce NOW on the 32:9 monitor:** the service only streams 16:9 (and some 21:9) aspect
|
||||||
ratios, so expect pillarboxing at 5120x1440 — that's a service limitation, not a config problem.
|
ratios, so expect pillarboxing at 5120x1440 — that's a service limitation, not a config problem.
|
||||||
|
|
||||||
|
## Development setup
|
||||||
|
|
||||||
|
All 29 projects in `~/Documents/Development` were scanned for toolchain needs — the full
|
||||||
|
mapping (what the image covers, mise versions, the native-build distrobox, hardware udev rules)
|
||||||
|
is in [DEVELOPMENT.md](DEVELOPMENT.md). After first boot, run
|
||||||
|
[scripts/dev-setup.sh](scripts/dev-setup.sh) to set it all up.
|
||||||
|
|
||||||
## Post-install steps (manual by design — don't automate these)
|
## Post-install steps (manual by design — don't automate these)
|
||||||
|
|
||||||
### PIA VPN — native WireGuard, not the app
|
### PIA VPN — native WireGuard, not the app
|
||||||
@@ -187,6 +143,14 @@ access / Intune compatibility): `flatpak install flathub com.microsoft.Edge`, si
|
|||||||
No official Linux app. Open <https://claude.ai> in Edge (or any Chromium browser) and use
|
No official Linux app. Open <https://claude.ai> in Edge (or any Chromium browser) and use
|
||||||
**Install this site as an app** the same way.
|
**Install this site as an app** the same way.
|
||||||
|
|
||||||
|
### AnythingLLM — not on Flathub
|
||||||
|
|
||||||
|
No Flatpak exists (verified 2026-07: zero Flathub search hits). Options: the official desktop
|
||||||
|
AppImage from [anythingllm.com](https://anythingllm.com/desktop) (works fine on atomic distros —
|
||||||
|
keep it in `~/Apps` and use e.g. Gear Lever to integrate it), or run the server edition in a
|
||||||
|
container: `docker run -p 3001:3001 mintplexlabs/anythingllm` (add
|
||||||
|
`--device nvidia.com/gpu=all` for 5090 acceleration).
|
||||||
|
|
||||||
### Proton-GE
|
### Proton-GE
|
||||||
|
|
||||||
Already handled by Bazzite: use the preinstalled **ProtonUp-Qt** GUI (or browse `ujust` — run
|
Already handled by Bazzite: use the preinstalled **ProtonUp-Qt** GUI (or browse `ujust` — run
|
||||||
@@ -212,13 +176,14 @@ 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), commit,
|
||||||
rebuild (see "Building & publishing"), and the next OS update picks it up. (Removing an app
|
and re-run `bluebuild switch`. (Removing an app from the list does not uninstall it from the
|
||||||
from the list does not uninstall it from the machine; `flatpak uninstall` it once by hand.)
|
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, rebuild, then update normally.
|
ready, then `bluebuild switch`.
|
||||||
- **Pull in base-image updates:** just rebuild — the base tag is `stable-44`, so each rebuild
|
- **Reclaim build disk:** `bluebuild prune` cleans build caches.
|
||||||
picks up the newest Bazzite build within Fedora 44.
|
- **Publishing later:** if this ever moves to a registry + signed rebases, the pieces are in
|
||||||
- **Key hygiene:** `cosign.key` is git-ignored and lives only on the workstation + in the
|
place — `cosign.pub` is committed, the signing module is in the recipe, and
|
||||||
`SIGNING_SECRET` secret — keep a backup (password manager). Losing it means generating a new
|
`bluebuild build --push --registry <host> --registry-namespace <ns>` does the rest (note:
|
||||||
pair, updating the secret, and re-doing the two-step rebase to re-establish trust.
|
as of CLI v0.9.36, local `build` runs bake the signing policy for `localhost` — a registry
|
||||||
|
push should be done from CI or with a `bluebuild generate`-based two-step).
|
||||||
|
|||||||
+7
-2
@@ -39,13 +39,18 @@ modules:
|
|||||||
- org.libreoffice.LibreOffice
|
- org.libreoffice.LibreOffice
|
||||||
- org.mozilla.Thunderbird
|
- org.mozilla.Thunderbird
|
||||||
- org.mozilla.firefox
|
- org.mozilla.firefox
|
||||||
|
- org.prismlauncher.PrismLauncher
|
||||||
# -- Community / unverified listings (see README) --
|
# -- Community / unverified listings (see README) --
|
||||||
|
- com.google.AndroidStudio # native-angular android-host (SDK 35 + NDK)
|
||||||
- com.makemkv.MakeMKV
|
- com.makemkv.MakeMKV
|
||||||
|
- com.spotify.Client
|
||||||
- io.github.hmlendea.geforcenow-electron # unofficial wrapper; 16:9/21:9 streams only
|
- io.github.hmlendea.geforcenow-electron # unofficial wrapper; 16:9/21:9 streams only
|
||||||
- io.github.shiftey.Desktop # GitHub Desktop Linux fork; "shiftey" is correct
|
- io.github.shiftey.Desktop # GitHub Desktop Linux fork; "shiftey" is correct
|
||||||
- org.godotengine.Godot
|
- org.godotengine.Godot
|
||||||
- org.videolan.VLC
|
- org.videolan.VLC
|
||||||
|
|
||||||
# Installs the cosign public key + container signature-verification policy
|
# Installs the cosign public key + container signature-verification policy.
|
||||||
# so `bootc`/`rpm-ostree` signed rebases work. Requires cosign.pub at repo root.
|
# Unused in the current build-locally model (`bluebuild switch` rebases from a
|
||||||
|
# local oci-archive, unsigned) — kept so publishing to a registry later only
|
||||||
|
# requires a push, not a recipe change. Requires cosign.pub at repo root.
|
||||||
- type: signing
|
- type: signing
|
||||||
|
|||||||
Executable
+35
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# One-shot developer toolchain setup for the main-desktop image.
|
||||||
|
# Run as your user after first boot (safe to re-run). See DEVELOPMENT.md for the why.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "== Homebrew tools =="
|
||||||
|
brew install mise gh cosign
|
||||||
|
|
||||||
|
echo "== Toolchains (mise) =="
|
||||||
|
mise use -g node@22 python@3.12 go@latest rust@latest java@temurin-21 dotnet@10
|
||||||
|
mise install node@18 node@20 python@3.11 java@temurin-17 java@temurin-25
|
||||||
|
|
||||||
|
echo "== RTL-SDR udev rules (FRScanner) =="
|
||||||
|
if [ ! -f /etc/udev/rules.d/20-rtlsdr.rules ]; then
|
||||||
|
sudo tee /etc/udev/rules.d/20-rtlsdr.rules >/dev/null <<'EOF'
|
||||||
|
# Generic RTL2832U (rtl-sdr) dongles — allow non-root access
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", MODE="0666", TAG+="uaccess"
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2832", MODE="0666", TAG+="uaccess"
|
||||||
|
EOF
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "== Native-build distrobox =="
|
||||||
|
if ! distrobox list 2>/dev/null | grep -q '^.*| *dev '; then
|
||||||
|
distrobox create --yes dev --image registry.fedoraproject.org/fedora:44
|
||||||
|
distrobox enter dev -- sudo dnf install -y gcc gcc-c++ make cmake pkgconf python3-devel \
|
||||||
|
gtk4-devel zbar libsndfile mediainfo-libs rtl-sdr rtl-sdr-devel mkvtoolnix \
|
||||||
|
python3-tkinter python3-dbus flashrom
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "== Done =="
|
||||||
|
echo "Remaining manual bits (see DEVELOPMENT.md):"
|
||||||
|
echo " - copy ~/godot/ (pinned 4.2/4.3 binaries) and ~/.local/share/godot/ from old machine"
|
||||||
|
echo " - bring per-project .env files (API keys)"
|
||||||
|
echo " - ujust dx-group (docker group), then re-login"
|
||||||
Reference in New Issue
Block a user