171 lines
8.4 KiB
Markdown
171 lines
8.4 KiB
Markdown
# main-desktop
|
|
|
|
Custom [Bazzite DX](https://github.com/ublue-os/bazzite-dx) image for my desktop, defined with
|
|
[BlueBuild](https://blue-build.org). **There is no published image** — clone this repo and build
|
|
it yourself; `bluebuild switch` rebases the running system straight onto the local build.
|
|
|
|
- **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
|
|
is exactly what the RTX 5090 (Blackwell) requires. Current stable ships driver **610.x** (open).
|
|
- **Pinned** to Fedora 44 via `image-version: stable-44` in
|
|
[recipes/recipe.yml](recipes/recipe.yml). No surprise major upgrades; bump to `stable-45`
|
|
deliberately.
|
|
- **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
|
|
automatic CDI setup** (`ublue-nvctk-cdi.service` regenerates `/etc/cdi/nvidia.yaml` each boot).
|
|
What this recipe adds: a declarative first-boot Flatpak set (and a dormant signing policy).
|
|
That's it — by design.
|
|
|
|
Why BlueBuild instead of a raw Containerfile: the whole custom layer is "install these Flatpaks
|
|
on first boot", which the `default-flatpaks` module expresses declaratively — and
|
|
`bluebuild switch` gives a one-command build-and-rebase with no registry involved.
|
|
|
|
## Getting onto this image (fresh desktop rebuild)
|
|
|
|
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:
|
|
|
|
```bash
|
|
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
|
|
cd main-desktop && git pull && bluebuild update recipes/recipe.yml --reboot
|
|
```
|
|
|
|
Roll back anytime with `rpm-ostree rollback` (or pick the previous deployment in the boot menu).
|
|
|
|
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
|
|
publishing signed images to a registry later is just a `bluebuild build --push` away.
|
|
|
|
## Install-time checklist
|
|
|
|
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`
|
|
(the proprietary module says `NVIDIA`). Blackwell only works on the open modules.
|
|
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.
|
|
3. **Flatpaks:** all installed (`flatpak list --system` — 19 apps from the list below).
|
|
4. **Docker group:** run `ujust dx-group` (adds you to `docker` and friends), then log out/in.
|
|
5. **GPU in containers:** run the one-liner test in the next section.
|
|
|
|
## GPU in containers (CUDA on the 5090)
|
|
|
|
`nvidia-container-toolkit` is already in the image and a boot service generates the CDI spec
|
|
automatically. CDI is the shipped mechanism:
|
|
|
|
```bash
|
|
# Podman — works out of the box:
|
|
podman run --rm --device nvidia.com/gpu=all docker.io/nvidia/cuda:12.8.0-base-ubuntu24.04 nvidia-smi
|
|
|
|
# Docker — CDI device syntax also works on current Docker CE:
|
|
docker run --rm --device nvidia.com/gpu=all nvidia/cuda:12.8.0-base-ubuntu24.04 nvidia-smi
|
|
```
|
|
|
|
If you want the classic `docker run --gpus all` syntax, that needs a one-time runtime hookup
|
|
(this writes to `/etc/docker/daemon.json`, which is mutable and survives updates):
|
|
|
|
```bash
|
|
sudo nvidia-ctk runtime configure --runtime=docker
|
|
sudo systemctl restart docker
|
|
```
|
|
|
|
## First-boot Flatpaks
|
|
|
|
Installed system-wide from Flathub by the `default-flatpaks` module. All IDs verified against
|
|
Flathub (2026-07).
|
|
|
|
**Official / verified listings:** Bambu Studio, Bitwarden, Discord, Firefox, Thunderbird,
|
|
FreeCAD, GIMP, HandBrake, LibreOffice, Moonlight, PCSX2 (`net.pcsx2.PCSX2` — the official
|
|
build), Podman Desktop, Warzone 2100, XIVLauncher (`dev.goats.xivlauncher`).
|
|
|
|
**Community / unverified listings — know what you're running:**
|
|
|
|
| App | ID | Note |
|
|
|---|---|---|
|
|
| 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 |
|
|
| GeForce NOW | `io.github.hmlendea.geforcenow-electron` | **Unofficial** Electron wrapper, not an NVIDIA product |
|
|
| VLC | `org.videolan.VLC` | No verified badge on Flathub (still the VideoLAN-maintained build) |
|
|
| 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
|
|
ratios, so expect pillarboxing at 5120x1440 — that's a service limitation, not a config problem.
|
|
|
|
## Post-install steps (manual by design — don't automate these)
|
|
|
|
### PIA VPN — native WireGuard, not the app
|
|
|
|
The PIA desktop app installs into `/usr` and breaks on the read-only filesystem. Skip it:
|
|
|
|
1. Log in at PIA's [OpenVPN config generator](https://www.privateinternetaccess.com/pages/ovpn-config-generator)
|
|
(or generate a WireGuard config via their API/support flow) and download configs for your
|
|
preferred regions.
|
|
2. KDE **System Settings → Network → Connections → Add (+) → Import VPN connection…**, pick the
|
|
downloaded file, and enter your PIA credentials.
|
|
3. This is plain NetworkManager — it lives in `/etc`, survives every update, and gets a
|
|
connect/disconnect toggle in the system tray.
|
|
|
|
### Microsoft Teams — PWA via Edge
|
|
|
|
No native Linux client. Install **Microsoft Edge specifically** (corporate conditional
|
|
access / Intune compatibility): `flatpak install flathub com.microsoft.Edge`, sign in to
|
|
<https://teams.microsoft.com>, then menu → **Apps → Install this site as an app**.
|
|
|
|
### Claude desktop — PWA
|
|
|
|
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.
|
|
|
|
### Proton-GE
|
|
|
|
Already handled by Bazzite: use the preinstalled **ProtonUp-Qt** GUI (or browse `ujust` — run
|
|
`ujust` with no arguments to list recipes). Don't install anything extra.
|
|
|
|
## Node / toolchains — not in the image
|
|
|
|
Node, npm, etc. are deliberately **not layered**. Use per-project versions instead:
|
|
|
|
```bash
|
|
brew install mise # Homebrew ships in the base image
|
|
mise use node@22 # per-project .mise.toml; `mise use -g node@22` for a global default
|
|
```
|
|
|
|
(Plain `brew install node` also works if you just want one global Node.)
|
|
|
|
## Display note
|
|
|
|
The 49" 32:9 (5120x1440) ultrawide needs nothing at the image layer. Post-install: set scale and
|
|
refresh rate in KDE System Settings → Display; KDE's window tiling (Meta+drag, or a tiler like
|
|
Polonium) is worth setting up at this width. VMs are remote via Remmina — there is intentionally
|
|
no local hypervisor tooling in this image.
|
|
|
|
## Maintenance
|
|
|
|
- **Change the Flatpak list / packages:** edit [recipes/recipe.yml](recipes/recipe.yml), commit,
|
|
and re-run `bluebuild switch`. (Removing an app 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
|
|
ready, then `bluebuild switch`.
|
|
- **Reclaim build disk:** `bluebuild prune` cleans build caches.
|
|
- **Publishing later:** if this ever moves to a registry + signed rebases, the pieces are in
|
|
place — `cosign.pub` is committed, the signing module is in the recipe, and
|
|
`bluebuild build --push --registry <host> --registry-namespace <ns>` does the rest (note:
|
|
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).
|