Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
main-desktop
Custom Bazzite DX image for my desktop, defined with
BlueBuild. 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-openDX 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-44in recipes/recipe.yml. No surprise major upgrades; bump tostable-45deliberately. - 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.serviceregenerates/etc/cdi/nvidia.yamleach 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)
-
Install stock Bazzite DX (NVIDIA) from the official ISO at bazzite.gg and boot into it.
-
Install the BlueBuild CLI and switch:
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 doneswitchbuilds the image locally, stores it as an oci-archive under/etc/bluebuild/, and rebasesrpm-ostreeonto it. First build pulls the multi-GB base — give it time and disk (~25 GB free). -
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):
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
- Driver sanity:
nvidia-smireports driver ≥ 580 (currently 610.x) and the RTX 5090 is listed. Confirm open kernel modules:modinfo -F license nvidiashould sayDual MIT/GPL(the proprietary module saysNVIDIA). Blackwell only works on the open modules. - Deployment:
rpm-ostree statusshows the booted deployment is the local build (ostree-unverified-image:oci-archive:/etc/bluebuild/...) with the expected base version. - Flatpaks: all installed (
flatpak list --system— 23 apps from the list below). The 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. - Docker group: run
ujust dx-group(adds you todockerand friends), then log out/in. - 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:
# 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):
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, OpenSCAD, PCSX2 (net.pcsx2.PCSX2 — the
official build), Podman Desktop, Prism Launcher, Warzone 2100, XIVLauncher
(dev.goats.xivlauncher).
Community / unverified listings — know what you're running:
| 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 |
| MakeMKV | com.makemkv.MakeMKV |
Community packaging of the proprietary app |
| 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) |
| 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.
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. After first boot, run
scripts/dev-setup.sh to set it all up.
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:
- Log in at PIA's OpenVPN config generator (or generate a WireGuard config via their API/support flow) and download configs for your preferred regions.
- KDE System Settings → Network → Connections → Add (+) → Import VPN connection…, pick the downloaded file, and enter your PIA credentials.
- 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.
AnythingLLM — not on Flathub
No Flatpak exists (verified 2026-07: zero Flathub search hits). Options: the official desktop
AppImage from anythingllm.com (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
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:
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, commit,
and re-run
bluebuild switch. (Removing an app from the list does not uninstall it from the machine;flatpak uninstallit once by hand.) - Jump Fedora majors: change
image-version: stable-44→stable-45in the recipe when ready, thenbluebuild switch. - Reclaim build disk:
bluebuild prunecleans build caches. - Publishing later: if this ever moves to a registry + signed rebases, the pieces are in
place —
cosign.pubis committed, the signing module is in the recipe, andbluebuild build --push --registry <host> --registry-namespace <ns>does the rest (note: as of CLI v0.9.36, localbuildruns bake the signing policy forlocalhost— a registry push should be done from CI or with abluebuild generate-based two-step).