1. Architecture Overview
Bazzite is a gaming-focused Linux distribution built as an OCI container image on top of Fedora Atomic Desktop (Silverblue/Kinoite) through the Universal Blue (ublue-os) framework. The system is immutable: the root filesystem is delivered as a container image, updates are atomic image replacements, and user customization happens through overlay mechanisms (/etc, Flatpak, Distrobox, Homebrew).
The build pipeline produces multiple image variants from a single Containerfile using multi-stage targets. Each variant combines a Fedora Atomic base with Bazzite's custom kernel, patched system packages (via RPM spec files), desktop environment presets, hardware-specific configurations, and a library of ujust administrative recipes.
Architecture Diagram
┌─────────────────────────────────────────────────────────┐
│ Bazzite Image │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ Fedora Atomic │ │ Bazzite │ │ Hardware │ │
│ │ Base Layer │ │ Overlay │ │ Profiles │ │
│ │ (Silverblue │ │ (packages, │ │ (WirePlumber, │ │
│ │ or Kinoite) │ │ configs, │ │ PipeWire, │ │
│ │ │ │ services) │ │ udev, EDID) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬────────┘ │
│ └─────────────┬───┘─────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐│
│ │ Containerfile (multi-target) ││
│ │ Targets: bazzite | bazzite-deck | bazzite-nvidia ││
│ └─────────────────────────────────────────────────────┘│
│ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌────────────────────────┐│
│ │ just │ │ systemd │ │ Desktop Environment ││
│ │ recipes │ │ services │ │ GNOME / KDE presets ││
│ │ (ujust) │ │ & timers │ │ Extensions, themes, ││
│ │ │ │ │ │ dconf/gsettings ││
│ └──────────┘ └──────────┘ └────────────────────────┘│
└─────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────────┐
│ Flatpak │ │ Distrobox │
│ (user apps) │ │ (mutable Linux) │
└─────────────┘ └─────────────────┘
Component Inventory
| Component | Path | Role |
|---|---|---|
| Containerfile | /Containerfile |
Multi-target container image build definition |
| Justfile | /Justfile |
Developer build/test/ISO recipes |
| just_scripts/ | /just_scripts/ |
Shell scripts backing Justfile recipes |
| build_files/ | /build_files/ |
Image build helpers (initramfs, kernel, cleanup) |
| system_files/ | /system_files/ |
Files overlaid onto the OS image during build |
| spec_files/ | /spec_files/ |
Custom RPM spec files and patches for forked packages |
| installer/ | /installer/ |
ISO installer (Anaconda config, branding, flatpak lists) |
| firmware/ | /firmware/ |
Custom firmware blobs (EDID, audio DSP) |
| tests/ | /tests/ |
dgoss-based container image tests |
| press_kit/ | /press_kit/ |
Brand assets, logos, promotional artwork |
Technology Stack
| Layer | Technology |
|---|---|
| Base OS | Fedora Atomic Desktop (Silverblue/Kinoite) |
| Image format | OCI container image via bootc |
| Package management | rpm-ostree (system), Flatpak (apps), Homebrew (CLI tools), Distrobox (mutable containers) |
| Build system | just (Justfile) + shell scripts + podman/docker |
| Desktop | GNOME (Silverblue) or KDE Plasma (Kinoite) |
| Compositor | Mutter (GNOME) / KWin (KDE) / Gamescope (Game Mode) |
| Audio | PipeWire + WirePlumber with hardware-specific profiles |
| Installer | Anaconda (Fedora) with custom branding and kickstart scripts |
| Testing | dgoss (Docker/container Goss testing) |
| Image signing | Cosign (Sigstore) with public key at /cosign.pub |
| Secure Boot | MOK enrollment via mokutil with Universal Blue certificate |
| CI/CD | GitHub Actions (container builds, published to ghcr.io/ublue-os/) |
Note
Bazzite does not run its own API server or web service — it is purely an OS image. The "architecture" is the image build pipeline and the runtime configuration it produces.
2. System Requirements
Build Requirements
| Component | Requirement |
|---|---|
| Container runtime | podman or docker (rootful for ISO builds) |
just |
Task runner — cargo install just or package manager |
| Disk space | 40 GB+ for image builds, 80 GB+ for ISO builds |
| RAM | 8 GB+ recommended for builds |
| KVM | Required for run-iso (QEMU-based ISO testing) |
| Git | For cloning the repository |
Runtime Requirements
| Component | Requirement |
|---|---|
| Architecture | x86_64 only |
| Boot mode | UEFI (Secure Boot optional) |
| Storage | 20 GB minimum, 64 GB+ recommended (Btrfs preferred) |
| GPU | AMD (open-source), Intel (open-source), NVIDIA (proprietary via -nvidia variants) |
| Network | Required for initial image pull and updates |
3. Configuration Reference
System Files Hierarchy
Bazzite overlays configuration files onto the Fedora base during image build. Files are organized by variant:
system_files/
├── desktop/ # All desktop variants
│ ├── shared/ # Common to GNOME + KDE desktop
│ │ ├── etc/ # /etc overrides
│ │ └── usr/ # /usr additions
│ ├── silverblue/ # GNOME-specific
│ └── kinoite/ # KDE-specific
├── deck/ # Handheld/HTPC (Game Mode) variants
│ ├── shared/ # Common to all deck
│ ├── silverblue/ # Deck + GNOME
│ └── kinoite/ # Deck + KDE
├── nvidia/ # NVIDIA GPU variants
│ ├── shared/ # Common NVIDIA
│ ├── silverblue/ # NVIDIA + GNOME
│ └── kinoite/ # NVIDIA + KDE
└── overrides/ # Applied to ALL variants (branding, CLI tools)
Key Configuration Files
| File | Location in Image | Purpose |
|---|---|---|
zram-generator.conf |
/etc/systemd/ |
ZRAM swap configuration |
distrobox.ini |
/etc/distrobox/ |
Default Distrobox container config |
topgrade.toml |
/etc/ublue-os/ |
Topgrade update tool configuration |
dnf.conf |
/etc/dnf/ |
DNF package manager settings |
mimeapps.list |
/etc/xdg/ |
Default MIME type associations |
weston.ini |
/etc/xdg/weston/ |
Weston compositor fallback config |
yafti.yml |
/usr/share/yafti/ |
First-boot setup wizard definition |
flatpak-blocklist |
/usr/share/ublue-os/ |
Flatpaks blocked from auto-install |
Environment Variables
| Variable | Location | Value | Purpose |
|---|---|---|---|
SUDO_ASKPASS |
/etc/profile.d/askpass.sh |
/usr/bin/ksshaskpass (KDE) or /usr/libexec/openssh/gnome-ssh-askpass (GNOME) |
GUI sudo password prompt |
GSK_RENDERER |
/etc/environment.d/99-nvidia-fix.conf |
gl |
NVIDIA: fix GTK4 apps not opening (installer live session) |
CONTAINER_RUNTIME |
Test scripts | podman |
Force dgoss to use podman |
Sysctl Parameters
| File | Key Parameters |
|---|---|
60-kernel.conf (desktop + deck) |
Kernel performance tuning |
70-gaming.conf |
Gaming-specific kernel parameters |
75-networking.conf |
Network stack optimization |
80-inotify.conf |
Increased inotify watches for large game libraries |
Kernel Module Configuration
| File | Purpose |
|---|---|
/etc/modules-load.d/wine-ntsync.conf |
Load ntsync for Wine/Proton |
/etc/modules-load.d/hid-steaminput-preload.conf |
Preload Steam Input HID module (Deck) |
/etc/modprobe.d/deck-blacklist.conf |
Blacklist conflicting modules on Deck hardware |
Security Limits
| File | Setting |
|---|---|
/etc/security/limits.d/memlock.conf |
Raised memlock limits for gaming |
/etc/security/rules.d/15-proton-nice.conf |
Allow Proton processes elevated nice priority (Deck) |
Important
All files under
/usrare immutable at runtime. To override, create corresponding files under/etcor userpm-ostree kargsfor kernel parameters. Changes to/usrrequire rebuilding the image.
Dracut Configuration
| File | Purpose |
|---|---|
/usr/lib/dracut/dracut.conf.d/80-vfio.conf |
VFIO passthrough support in initramfs |
4. Deployment & Scaling
Image Build Process
The Justfile provides the developer interface for building images and ISOs:
Build an image:
just build <target> <desktop>
| Parameter | Values | Default |
|---|---|---|
target |
bazzite, bazzite-deck, bazzite-nvidia |
bazzite |
desktop |
gnome, kde, silverblue, kinoite |
— |
The build script (just_scripts/build-image.sh) runs:
$container_mgr build -f Containerfile \
--build-arg="IMAGE_NAME=${tag}" \
--build-arg="BASE_IMAGE_NAME=${base_image}" \
--build-arg="KERNEL_FLAVOR=bazzite" \
--build-arg="SOURCE_IMAGE=${base_image}-${flavor}" \
--build-arg="FEDORA_VERSION=${latest}" \
--target="${target}" \
--tag localhost/"${tag}:${latest}-${git_branch}" \
"${project_root}"
Note
The build automatically selects
podman,docker, orpodman-remoteviajust_scripts/container_mgr.sh. SetCONTAINER_MGRenvironment variable to force a specific runtime.
Build an ISO:
just build-iso <target> <desktop>
ISO builds require a rootful container runtime (cannot run inside rootless podman). The process:
- Builds the container image if not already present
- Generates Flatpak dependency list using a temporary container
- Runs
ghcr.io/jasonn3/build-container-installerto produce the ISO
Warning
ISO builds cannot run inside rootless containers. The script checks for
/run/.containerenvand the root status of the container manager before proceeding.
Build arguments:
| Build Arg | Purpose |
|---|---|
IMAGE_NAME |
Container tag name |
BASE_IMAGE_NAME |
silverblue or kinoite |
KERNEL_FLAVOR |
Always bazzite (custom kernel) |
SOURCE_IMAGE |
Base image with flavor suffix (silverblue-main, kinoite-nvidia) |
FEDORA_VERSION |
Fedora release number |
ISO Configuration
The ISO is configured via installer/iso.yaml:
label: "Bazzite-Live"
grub2:
timeout: 3
entries:
- name: "Launch Bazzite Installer"
linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=Bazzite-Live enforcing=0 rd.live.image"
initrd: "/images/pxeboot/initrd.img"
- name: "Launch Bazzite Installer (Basic Graphics Mode)"
linux: "/images/pxeboot/vmlinuz quiet rhgb root=live:CDLABEL=Bazzite-Live enforcing=0 rd.live.image nomodeset"
initrd: "/images/pxeboot/initrd.img"
Container Registry
Built images are published to GitHub Container Registry:
ghcr.io/ublue-os/bazzite-gnome:42
ghcr.io/ublue-os/bazzite-kde:42
ghcr.io/ublue-os/bazzite-deck-gnome:42
ghcr.io/ublue-os/bazzite-gnome-nvidia:42
...
Images are signed with Cosign. The public key is at /cosign.pub in the repository root.
Test an Image Locally
just run-image <target> <desktop>
This starts the built image in an interactive container session.
Test an ISO in QEMU:
just run-iso <target> <desktop>
Runs the ISO in qemux/qemu-docker with KVM, accessible at http://127.0.0.1:8006. Configuration: 2 CPU cores, 4 GB RAM, 64 GB virtual disk, UEFI boot.
Cleanup
just clean-images # Remove built container images
just clean-dir # Remove built ISOs from output/
5. Operations
Systemd Services — Desktop Variants
| Service | Type | Purpose |
|---|---|---|
bazzite-hardware-setup.service |
system, oneshot | Hardware detection and configuration at boot |
bazzite-flatpak-manager.service |
system | Manage default Flatpak installations |
bazzite-libvirtd-setup.service |
system | Configure libvirt for virtualization |
bazzite-user-setup.service |
user | Per-user first-login configuration |
bazzite-dynamic-fixes.service |
user | Apply runtime fixes for known issues |
steam-icons-cleanup.service |
user | Clean up orphaned Steam desktop icons |
beesd@.timer |
system | Periodic Btrfs deduplication |
cec-onboot.service |
system | HDMI-CEC power-on signal |
cec-onsleep.service |
system | HDMI-CEC sleep signal |
cec-onpoweroff.service |
system | HDMI-CEC power-off signal |
force-wol.service |
system | Force Wake-on-LAN configuration |
ryzenadj.service |
system | Apply RyzenAdj power settings |
incus-workaround.service |
system | Incus container compatibility fix |
kmod-sleep-workaround@.service |
system | Kernel module sleep workaround |
dev-hugepages1G.mount |
system | Mount 1 GB hugepages |
dconf-update.service |
system (GNOME) | Recompile dconf database |
ntfs-nag.service |
user (GNOME/KDE) | Warn about NTFS/exFAT performance |
usr-share-sddm-themes.mount |
system (KDE) | Mount SDDM themes directory |
Tip
All services are enabled/disabled at image build time. Runtime enable/disable via
systemctlpersists across updates since/etc/systemdis in the mutable layer.
Systemd Services — Deck Variants
| Service | Type | Purpose |
|---|---|---|
bazzite-autologin.service |
system | Auto-login to Game Mode session |
bazzite-tdpfix.service |
system | TDP (power) fix for handhelds |
return-to-gamemode.service |
system | Return to Game Mode after desktop session |
pipewire-workaround.service |
system | PipeWire startup race condition fix |
wireplumber-workaround.service |
system | WirePlumber startup race condition fix |
ublue-update-force.service |
system | Force update on next boot |
steam-web-debug-portforward@.service |
system | Port forward for Steam web debugging |
ac.target / battery.target |
system | Power state targets for conditional services |
HHD (Handheld Daemon) Integration
Deck variants include systemd drop-in overrides for HHD services:
| Override | Purpose |
|---|---|
hhd@.service.d/override.conf |
Main HHD service customization |
hhd.service.d/override.conf |
HHD base service overrides |
hhdl.service.d/override.conf |
HHD local service overrides |
hhd_local@.service.d/override.conf |
HHD local instance overrides |
Polkit Rules
| Rule File | Purpose |
|---|---|
10-rebase.rules |
Allow rebase without root (Deck) |
20-privileged-ruser.rules |
Privileged user setup permissions |
30-waydroid.rules |
Waydroid container management permissions |
50-efibootmgr.rules |
EFI boot manager access (GNOME) |
70-hhd.rules |
HHD daemon permissions (Deck) |
90-corectrl.rules |
CoreCtrl GPU management permissions |
bazzite-autologin.rules |
Auto-login permission (Deck) |
return-to-gamemode.rules |
Game Mode return permission (Deck) |
ublue-update-force.rules |
Force update permission (Deck) |
udev Rules
| Rule File | Purpose |
|---|---|
30-steamdeck.rules |
Steam Deck hardware identification |
50-ally-fingerprint.rules |
ROG Ally fingerprint reader |
50-gpd-win-4-fingerprint.rules |
GPD Win 4 fingerprint reader |
50-gpd-wm2-fingerprint.rules |
GPD Win Mini 2 fingerprint reader |
50-lenovo-legion-controller.rules |
Lenovo Legion controller |
50-wifi-sleep.rules |
WiFi power management on sleep |
60-schedulers.rules |
I/O scheduler selection |
80-gpu-reset.rules |
GPU reset on hang detection |
90-dolphin-motion.rules |
Dolphin emulator motion controls |
99-cec-bluetooth.rules |
CEC/Bluetooth coordination |
99-powertargets.rules |
AC/battery power target activation |
Note
The
99-powertargets.rulesfile activatesac.targetorbattery.targetbased on power state, enabling conditional service activation.
Announcements System
Bazzite includes a built-in announcement system for notifying users of breaking changes:
File format: JSON files at /usr/share/ublue-os/announcements/ with .msg.json suffix.
{
"title": "Breaking change",
"body": "Description of the change",
"seeMoreUrl": "https://example.com/details",
"if": "systemd-analyze compare-versions 43 \\< $(rpm-ostree status -v --json | jq -r '.deployments[]|select(.booted==true)|.version')"
}
| Field | Required | Purpose |
|---|---|---|
title |
Yes | Category (1-2 words): "Breaking change", "Announcement" |
body |
Yes | Short paragraph explaining the announcement |
seeMoreUrl |
No | URL opened when user clicks "See more" |
if |
No | Shell command; exit code 1 skips the announcement |
The prepare_msg.sh script creates announcement JSON interactively.
Tip
Use the
iffield to schedule announcements ahead of time — they trigger only when the system updates to a matching version.
Update Flow
uupd.timertriggers periodic update checksbootc switch --mutate-in-placepulls the new image- Image is staged as a new deployment
- On reboot, the new deployment becomes active
- Previous deployment remains available for rollback
Greenboot Health Checks
Bazzite configures Greenboot for boot health verification:
/etc/greenboot/greenboot.conf
If health checks fail after an update, Greenboot automatically rolls back to the previous deployment.
6. Performance
Tuned Profiles
Bazzite ships custom tuned profiles with sched_ext scheduler integration:
| Profile | Scheduler Mode | USB Autosuspend | WiFi Powersave |
|---|---|---|---|
balanced-bazzite |
auto |
No | No |
throughput-performance-bazzite |
gaming |
No | No |
powersave-bazzite |
powersave |
Configurable | Enabled |
balanced-battery-bazzite |
— | No | No |
powersave-battery-bazzite |
— | No | No |
Profile scripts are at /usr/lib/tuned/profiles/*/script.sh. Each uses scxctl switch -m <mode> to set the sched_ext scheduler when scx_loader.service is enabled.
Kernel Parameters
Desktop (/usr/lib/sysctl.d/):
| File | Key Tunings |
|---|---|
60-kernel.conf |
Core kernel performance parameters |
70-gaming.conf |
Gaming-specific (scheduler, memory) |
75-networking.conf |
Network stack optimization |
80-inotify.conf |
Increased inotify limits |
Deck (/usr/lib/sysctl.d/):
| File | Key Tunings |
|---|---|
60-kernel.conf |
Kernel parameters for handheld use |
65-memory.conf |
Memory management for constrained RAM |
Logind Configuration (Deck)
/etc/systemd/logind.conf.d/deck.conf — Session handling for Game Mode
/usr/lib/systemd/logind.conf.d/killuserprocesses.conf — Kill user processes on logout
Journal Configuration (Deck)
/usr/lib/systemd/journald.conf.d/00-journal-persistent.conf — Persistent journal storage
/usr/lib/systemd/journald.conf.d/00-journal-size.conf — Journal size limits
7. Security
Image Signing
All official Bazzite images are signed with Cosign (Sigstore). The public key is distributed at:
- Repository:
/cosign.pub - Image:
/usr/share/ublue-os/sb_pubkey.der(Secure Boot variant)
The verification script (/etc/profile.d/verify_motd.sh) checks at login whether the running deployment is signed:
CURRENT_REF=$(rpm-ostree status --json | jq -r '.deployments[0]["container-image-reference"] // empty')
if [[ "$CURRENT_REF" == *"ostree-unverified-registry"* ]] && [[ "$CURRENT_REF" == *"ghcr.io/ublue-os/"* ]]; then
# Display security warning
fi
Warning
Running an unverified image disables automatic updates and container signature verification. Users see a red terminal warning on every login until resolved with
ujust verify-image.
Secure Boot
Bazzite supports UEFI Secure Boot via Machine Owner Key (MOK) enrollment:
- Enrollment password:
universalblue(hardcoded in installer) - Key URL:
https://github.com/ublue-os/akmods/raw/main/certs/public_key.der - Skip condition: Steam Deck (Jupiter/Galileo) hardware skips enrollment automatically
- Key location in image:
/usr/share/ublue-os/sb_pubkey.der
The installer generates a QR code linking to https://docs.bazzite.gg/sb for documentation.
Installer Security
The ISO installer includes security checks:
- BitLocker detection: Scans
lsblkfor BitLocker partitions and warns users with a dialog (including QR code to wikihow.com BitLocker disable guide) - Signed image switch: After installation,
bootc switch --enforce-container-sigpolicyensures the installed system uses signed images - EFI partition cleanup: Removes previous Fedora EFI entries to prevent boot confusion
SELinux
NVIDIA variants include a custom SELinux policy module:
/usr/share/selinux/packages/nvidia-container.pp
Caution
The live ISO boots with
enforcing=0(SELinux permissive) to avoid installer conflicts. The installed system runs in enforcing mode.
Polkit Security Boundaries
Polkit rules define privilege escalation boundaries. Key policies:
| Policy | Action |
|---|---|
org.bazzite.privileged.user.setup.policy |
First-boot privileged user setup |
org.bazzite.waydroid.policy |
Waydroid container management |
org.bazzite.hhd.policy |
HHD daemon control (Deck) |
org.bazzite.rebase.policy |
Image rebase without root (Deck) |
8. Developer Internals
Repository Structure
.
├── Containerfile # Multi-stage OCI image build
├── Justfile # Developer task runner
├── LICENSE # License
├── cosign.pub # Image signing public key
├── secure_boot.der # Secure Boot certificate
├── artifacthub-repo.yml # ArtifactHub registry metadata
├── build_files/ # Build-time scripts
│ ├── build-gnome-extensions # Compile GNOME Shell extensions
│ ├── build-initramfs # Regenerate initramfs
│ ├── cleanup # Post-build cleanup
│ ├── dnf5-search / dnf5-setopt # DNF5 helpers
│ ├── finalize # Final image preparation
│ ├── ghcurl # GitHub release downloader
│ ├── image-info # Write image metadata JSON
│ ├── install-kernel # Custom kernel installation
│ └── install-nvidia # NVIDIA driver installation
├── installer/ # ISO installer
│ ├── build.sh # ISO rootfs preparation
│ ├── iso.yaml # GRUB/ISO configuration
│ ├── Containerfile # Installer container build
│ ├── titanoboa_hook_*.sh # Pre/post rootfs hooks
│ ├── branding/ # Anaconda artwork
│ ├── gnome_flatpaks/flatpaks # Default GNOME Flatpaks
│ ├── kde_flatpaks/flatpaks # Default KDE Flatpaks
│ └── lorax_templates/ # Lorax customization
├── just_scripts/ # Shell scripts for Justfile
├── spec_files/ # Patched RPM specs (30+ packages)
├── system_files/ # Overlay files for image variants
├── firmware/ # Custom firmware blobs
├── tests/ # Container image tests
│ └── dgoss/ # dgoss test runner
└── press_kit/ # Brand assets
Forked Packages (spec_files/)
Bazzite maintains custom RPM spec files with patches for these upstream packages:
| Package | Key Patches | Purpose |
|---|---|---|
NetworkManager |
IWD 802.1X restriction removal | Better WiFi with iwd backend |
bluez |
Valve Bluetooth config, LL privacy, wake policy | Steam Deck Bluetooth optimization |
gamescope |
cstdint fix | Valve compositor for Game Mode |
gnome-shell |
GDM fingerprint workaround, custom patches | GNOME desktop fixes |
mutter |
PAC config callback fix, custom patches | GNOME compositor fixes |
pipewire |
Custom patch | Audio pipeline fixes |
wireplumber |
Steam default clear block | Prevent Steam from clearing audio defaults |
mangohud |
Multiple upstream patches | Performance overlay fixes |
lutris |
evdev 1.9.0 fix, game installation fix | Game launcher compatibility |
umu-launcher |
(custom spec) | Valve's unified game launcher |
steamdeck-dsp |
Bazzite + Fedora patches | Steam Deck audio DSP |
steamdeck-kde-presets |
Bazzite branding, Fedora compat, multiuser | KDE presets for Deck |
steamdeck-gnome-presets |
Add-to-Steam Nautilus extension | GNOME presets for Deck |
jupiter-fan-control |
Fedora patch | Steam Deck fan control |
jupiter-hw-support |
Btrfs, NTFS, automount, SELinux patches | Steam Deck hardware support |
anaconda |
Bazzite patch | Installer customization |
iwd |
Unprivileged access, scan segfault fix | WiFi daemon fixes |
upower |
Valve patch | Power management for Deck |
bees |
Patches #286, #309 | Btrfs deduplication fixes |
fedora-logos |
Bazzite branding | Replace Fedora logos |
gsettings-desktop-schemas |
RHEL override | Desktop schema customization |
galileo-mura |
Valve + Fedora patches | Steam Deck OLED mura correction |
rom-properties |
(custom spec) | Game ROM file properties |
ds-inhibit |
Fedora patch | DualSense inhibit support |
powerbuttond |
(custom spec) | Power button daemon |
steam_notif_daemon |
(custom spec) | Steam notification daemon |
vpower |
Fedora patch | Virtual power management |
bazzite_updater |
(custom spec) | System updater component |
xorg-x11-server-Xwayland |
Revert commit restrictions, pointer warp fix | XWayland compatibility |
Hardware Profiles
WirePlumber Profiles
Device-specific audio routing at /usr/share/wireplumber/hardware-profiles/:
| Device | Profile Path | Key Configuration |
|---|---|---|
| ASUS ROG Ally | asustek...rc71l_rc71l/ |
HDMI preference, ALSA card routing |
| ASUS ROG Ally X | asustek...rc72la_rc72la/ |
HDMI preference, ALSA card routing |
| Lenovo Legion Go | lenovo-83e1/ |
HDMI preference, internal mic boost, ALSA routing |
| GPD Win 4/G1618-05 | gpd-g1618-05/ |
Custom WirePlumber config |
| MSI Claw A1M | micro-star...claw-a1m/ |
ALSA headroom |
| MSI Claw 7 AI+ | micro-star...claw-7-ai+/ |
ALSA headroom |
| MSI Claw 8 AI+ | micro-star...claw-8-ai+/ |
ALSA headroom |
| Framework Desktop (AMD Ryzen AI Max) | framework-desktop.../ |
HDMI preference, mic boost |
Global WirePlumber config at /usr/share/wireplumber/wireplumber.conf.d/:
| File | Purpose |
|---|---|
alsa-card0.conf |
ALSA card 0 routing |
alsa-card1.conf |
ALSA card 1 routing |
alsa-ps-controller.conf |
PlayStation controller audio |
bluez.conf |
Bluetooth audio configuration |
51-disable-suspension.conf |
Prevent audio device suspension (desktop) |
PipeWire Filter Chains
Device-specific DSP at /usr/share/pipewire/hardware-profiles/:
| Device | Configuration |
|---|---|
| Lenovo Legion Go | filter-chain.conf + multiwayCor48.wav |
| ASUS ROG Ally | filter-chain.conf + game.wav |
| GPD Win 4 | pipewire.conf |
| GPD Win Mini | filter-chain.conf |
Display Profiles
Gamescope display configuration at /usr/share/gamescope/scripts/00-gamescope/displays/:
| File | Device | Refresh Range |
|---|---|---|
gpd.win4.lcd.lua |
GPD Win 4 | 31-60 Hz dynamic |
The Lua script defines colorimetry, HDR capabilities, and dynamic mode generation for per-device display support.
Color Profiles (ICC)
| File | Device |
|---|---|
Steam_Deck.icc |
Steam Deck LCD |
Steam_Deck_Matte.icc |
Steam Deck LCD (matte screen) |
Legion_GO_BT1886.icc |
Lenovo Legion Go |
framework13.icc |
Framework 13 |
framework16.icc |
Framework 16 |
EDID Firmware
Custom EDID blobs at /usr/lib/firmware/edid/:
| File | Purpose |
|---|---|
aokzoea1ar07_edid.bin |
Custom EDID for specific display panel |
sdoled_edid.bin |
Steam Deck OLED EDID |
ALSA UCM Profiles
/usr/share/alsa/ucm2/USB-Audio/Sony/DualSense-PS5.conf
Custom Use Case Manager profile for PS5 DualSense controller audio.
GNOME Shell Extensions
The GNOME (Silverblue) variant bundles these extensions:
| Extension | Purpose |
|---|---|
blur-my-shell@aunetx |
Blur effect on shell elements |
[email removed] |
Window open/close animations |
[email removed] |
3D desktop cube |
[email removed] |
Magic lamp minimize effect |
[email removed] |
Wobbly windows |
[email removed] |
Hot edge activation |
logomenu@aryan_k |
Logo menu in top bar |
[email removed] |
System tray app indicators |
[email removed] |
Add to Steam context menu |
[email removed] |
Restart-to boot menu entry |
[email removed] |
Block on-screen keyboard (removed on Deck) |
[email removed] |
Bazaar app store integration |
KDE Plasma Customization
Default taskbar pins (set via bazzite-pins.js Plasma update script):
widget.writeConfig("launchers", [
"preferred://browser",
"applications:steam.desktop",
"applications:net.lutris.Lutris.desktop",
"applications:org.kde.konsole.desktop",
"applications:io.github.kolunmi.Bazaar.desktop",
"applications:io.github.ublue_os.yafti_gtk.desktop",
"preferred://filemanager"
]);
Themes: Vapor (stock SteamOS theme, com.valve.vapor.desktop) and VGUI2 (green theme, com.valve.vgui.desktop) are available.
Templates: KDE file templates for MangoHud, DXVK, and vkBasalt configuration files.
Add-to-Steam Nautilus Extension
A Python Nautilus extension (steamos-add-to-steam.py) provides "Add to Steam" in the GNOME file manager:
class AddToSteamExtension(GObject.GObject, Nautilus.MenuProvider):
Supported MIME types:
application/x-desktopapplication/x-executableapplication/vnd.appimageapplication/x-shellscriptapplication/x-ms-dos-executable
The extension calls /usr/bin/steamos-add-to-steam with the selected file path.
Installer Internals
The installer pipeline (installer/titanoboa_hook_postrootfs.sh) performs:
- Remove all RPM versionlocks
- Install Anaconda, Firefox, block device libraries
- Install QR code generator (
qrencode) and dialog tool (yad) - Install Conky for live desktop hardware info display
- Detect image variant and apply branding
- Fetch and enroll Secure Boot key
- Generate Kickstart file with:
- BitLocker detection and warning dialog
- EFI partition cleanup
- Boot partition relabeling (
bazzite_xboot) - Error dialog on installation failure
- Deck variant: default user creation (
bazzite:bazzite) - Post-install: signed image switch, Flatpak install, SELinux relabel
- Disable non-essential services for live session
- Apply NVIDIA workarounds for live session (GSK_RENDERER, nouveau reinstall)
- Desktop-environment-specific setup (GNOME keyboard, KDE pins, wallpapers)
The pre-initramfs hook (installer/titanoboa_hook_preinitramfs.sh) swaps the custom kernel for a vanilla signed kernel to support Secure Boot on the live ISO.
Testing Framework
Tests use dgoss (Docker/container variant of Goss):
tests/dgoss/dgoss-tests.sh <tests-dir> <image-ref>
The runner:
- Sets
CONTAINER_RUNTIME=podman - Discovers
test.shscripts in test directories - Runs each test against the specified image
Current test suite: tests/dgoss/tests.d/00-smoke/ — basic smoke test that validates the container starts successfully.
dgoss run "${image}"
Hardware Support Detection Scripts
Utility scripts at /usr/libexec/hwsupport/:
| Script | Purpose |
|---|---|
sysid |
Read system DMI product name |
valve-hardware |
Detect Steam Deck (Jupiter/Galileo) |
needs-100-scale |
Detect displays needing 100% scaling |
needs-150-scale |
Detect displays needing 150% scaling |
needs-200-scale |
Detect displays needing 200% scaling |
needs-left-rotation |
Detect displays needing left rotation |
needs-right-rotation |
Detect displays needing right rotation |
ArtifactHub Registration
The repository is registered on ArtifactHub for OCI image discovery:
repositoryID: 6f68e5bb-ffaf-4a70-9c1b-b154b772044e
owners:
- name: Jorge Castro
email: [email removed]
Code Patterns
- Shell scripts dominate: The codebase is primarily bash scripts, systemd units, and configuration files. Only one Python file exists (
steamos-add-to-steam.py). - Variant selection via path convention:
system_files/{variant}/{de_base}/maps directly to the filesystem overlay applied during image build. - Conditional builds via Containerfile targets:
--target=bazzite-deckvs--target=bazzite-nvidiaselects the build variant. - Just as user-facing CLI: End users run
ujust <recipe>rather than raw system commands. Thejustrecipe files in/usr/share/ublue-os/just/are numbered for load order (10, 80-92, 95).
Known Issues and Workarounds
| Issue | Component | Workaround |
|---|---|---|
ujust update fails with rename error (#4204) |
rpm-ostree | rpm-ostree cleanup -p |
| Ethernet/WiFi drops (#2473) | NetworkManager/kernel | Reboot; apply updates |
| uupd fails on VPN (#4592) | uupd | Disconnect VPN for updates |
| Steam menu missing Desktop Mode switch (#4625) | Steam/Game Mode | Restart Steam or reboot |
| KDE services persist after exiting Game Mode (#4624) | KDE/systemd | Reboot to clean up |
| Fans run during sleep (#4593) | jupiter-fan-control | Apply updates |
| nct6687d module outdated (#3813) | kernel module | Pending: module update requested |
Contributing
- Fork the repository
- Create a branch for your change
- Make changes following the existing conventions:
- Shell scripts:
set -euo pipefail,shellcheckcompatible - System files: mirror the OS filesystem path structure under
system_files/ - Spec files: maintain upstream compatibility with Fedora specs
- Shell scripts:
- Test with
just build <target> <desktop>andjust run-image <target> <desktop> - Submit a pull request
Note
The dgoss test suite runs during CI. Ensure
tests/dgoss/tests.d/00-smoke/passes for your variant before submitting.
9. Integration Points
Universal Blue Ecosystem
Bazzite builds on the Universal Blue framework:
- Base images:
ghcr.io/ublue-os/silverblue-main,ghcr.io/ublue-os/kinoite-main - NVIDIA images:
ghcr.io/ublue-os/silverblue-nvidia,ghcr.io/ublue-os/kinoite-nvidia - Shared infrastructure: ublue-os akmods (kernel modules), bling (CLI tools), yafti (first-boot wizard)
- ISO builder:
ghcr.io/jasonn3/build-container-installer
Bazaar App Store
Bazzite integrates the Bazaar application store:
- Configuration at
/usr/share/ublue-os/bazaar/ - Content categories:
main.yaml,content.yaml - Blocklist:
blocklist.yaml - Custom hooks:
hooks.py - Category icons: gaming, music, office, streaming, utilities
Topgrade Integration
System updates are coordinated through Topgrade:
- Config:
/etc/ublue-os/topgrade.tomland/usr/share/ublue-os/topgrade.toml - Custom update scripts at
/usr/libexec/topgrade/:mozilla-gnome-theme-update— Update Firefox GNOME themethird-party-css-loader-update— Update CSS Loader themes
NetworkManager with iwd Backend
Bazzite configures NetworkManager to use iwd as the WiFi backend:
/usr/lib/NetworkManager/conf.d/50-iwd.conf — Set wifi.backend=iwd
/usr/lib/NetworkManager/conf.d/51-iwd-config.conf — iwd-specific settings
The custom iwd package includes a patch removing 802.1X restrictions for unknown networks.
NVIDIA Container Toolkit (NVIDIA Variants)
NVIDIA variants include container GPU support:
/usr/lib/systemd/system/ublue-nvctk-cdi.service — NVIDIA Container Toolkit CDI generation
/usr/libexec/nvidia-legacy-hardware — Legacy NVIDIA hardware detection
Distrobox Configuration
NVIDIA variant has a separate Distrobox configuration:
/etc/distrobox/distrobox.ini — Standard variant
/nvidia/shared/etc/distrobox/distrobox.ini — NVIDIA variant (includes GPU passthrough)