Jesse A. Green / notebook

Bazzite Administrator & Developer Guide

Generated May 2026 from ublue-os/bazzite at 405c0ed

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

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 /usr are immutable at runtime. To override, create corresponding files under /etc or use rpm-ostree kargs for kernel parameters. Changes to /usr require 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, or podman-remote via just_scripts/container_mgr.sh. Set CONTAINER_MGR environment 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:

  1. Builds the container image if not already present
  2. Generates Flatpak dependency list using a temporary container
  3. Runs ghcr.io/jasonn3/build-container-installer to produce the ISO

Warning

ISO builds cannot run inside rootless containers. The script checks for /run/.containerenv and 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 systemctl persists across updates since /etc/systemd is 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.rules file activates ac.target or battery.target based 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 if field to schedule announcements ahead of time — they trigger only when the system updates to a matching version.

Update Flow

  1. uupd.timer triggers periodic update checks
  2. bootc switch --mutate-in-place pulls the new image
  3. Image is staged as a new deployment
  4. On reboot, the new deployment becomes active
  5. 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:

  1. BitLocker detection: Scans lsblk for BitLocker partitions and warns users with a dialog (including QR code to wikihow.com BitLocker disable guide)
  2. Signed image switch: After installation, bootc switch --enforce-container-sigpolicy ensures the installed system uses signed images
  3. 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-desktop
  • application/x-executable
  • application/vnd.appimage
  • application/x-shellscript
  • application/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:

  1. Remove all RPM versionlocks
  2. Install Anaconda, Firefox, block device libraries
  3. Install QR code generator (qrencode) and dialog tool (yad)
  4. Install Conky for live desktop hardware info display
  5. Detect image variant and apply branding
  6. Fetch and enroll Secure Boot key
  7. 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
  8. Disable non-essential services for live session
  9. Apply NVIDIA workarounds for live session (GSK_RENDERER, nouveau reinstall)
  10. 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:

  1. Sets CONTAINER_RUNTIME=podman
  2. Discovers test.sh scripts in test directories
  3. 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-deck vs --target=bazzite-nvidia selects the build variant.
  • Just as user-facing CLI: End users run ujust <recipe> rather than raw system commands. The just recipe 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

  1. Fork the repository
  2. Create a branch for your change
  3. Make changes following the existing conventions:
    • Shell scripts: set -euo pipefail, shellcheck compatible
    • System files: mirror the OS filesystem path structure under system_files/
    • Spec files: maintain upstream compatibility with Fedora specs
  4. Test with just build <target> <desktop> and just run-image <target> <desktop>
  5. 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.toml and /usr/share/ublue-os/topgrade.toml
  • Custom update scripts at /usr/libexec/topgrade/:
    • mozilla-gnome-theme-update — Update Firefox GNOME theme
    • third-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)