Skip to content

Building from Source

This guide covers building Bazzite AI components locally.

Prerequisites

  • Just task runner installed (brew install just or cargo install just)
  • Podman or Docker for container builds
  • Git for source control

Building the OS Image

# Navigate to repository
cd bazzite-ai

# Build OS image with default tag (stable)
just build

# Build with custom tag
just build my-tag

# Build bootable ISO
just build-iso

Output Locations

Build Output
OS Image Pushed to GHCR (if configured)
ISO output/bootiso/

Building Pods

Single Pod

# Build specific variant
just pod build nvidia-python

# With custom tag
just pod build nvidia-python my-tag

All Pods

# Build all variants
just pod build all

# With custom tag
just pod build all my-tag

Available Pod Variants

  • base - CPU-only foundation
  • nvidia - CUDA/cuDNN
  • nvidia-python - PyTorch ML
  • jupyter - JupyterLab
  • devops - Cloud tools
  • playwright - Browser automation
  • githubrunner - CI/CD

Cache Control

# Rebuild without cache
just rebuild-pod my-tag none

# Use local cache only
just rebuild-pod my-tag local

# Use all caches (default)
just rebuild-pod my-tag all

Building Documentation

# Build documentation site
just docs-build

# Serve locally for preview
just docs-serve
# Open http://localhost:8000

Documentation System

  • Engine: MkDocs Material
  • Source: docs/ directory
  • Output: site/ directory
  • Config: mkdocs.yml

Pixi Lock Files

For pods using pixi (nvidia-python, jupyter, playwright):

# Generate lock file for specific variant
just generate-pixi-lock nvidia-python

# Generate all lock files
just generate-pixi-locks

Testing Builds

Test Pod

# Test CUDA access
just test-cuda-pod my-tag

# Test DevOps tools
just test-devops-pod my-tag

# Test GitHub runner
just test-githubrunner-pod my-tag

Test OS Changes

Use overlay testing for rapid iteration:

# Enable overlay (symlinks system_files to /usr)
just test overlay enable

# Test your changes
ujust <your-command>

# Disable overlay
just test overlay disable

Buildcache Architecture

Bazzite AI uses a unified buildcache strategy for efficiency:

Shared Scripts (build_files/shared/)
    OS Image  +  All Pod Variants
       ↓              ↓
   GHCR Push      GHCR Push

Cache Layers

The Containerfile is organized for maximum cache efficiency:

  1. Stable layers (packages, tools) - Rarely change
  2. Moderate layers (configurations) - Occasional changes
  3. Volatile layers (system_files) - Frequent changes

Changing a script only invalidates subsequent layers.

CI/CD Integration

GitHub Actions workflows:

Workflow Trigger Action
ci-validate.yml PR, Push Run pre-commit, validate syntax
build-os.yml Release, Manual Build and push OS image
build-pods.yml Release, Manual Build and push all pods
docs.yml Push to main Deploy documentation

Common Tasks

Add a Package to OS

  1. Edit appropriate script in build_files/os/ or build_files/shared/
  2. Test with overlay: just test overlay enable
  3. Rebuild: just build

Add a Tool to a Pod

  1. Edit pods/<variant>/Containerfile or build scripts
  2. Update pixi.toml if using pixi
  3. Rebuild: just pod build <variant>
  4. Test: podman run -it ghcr.io/atrawog/bazzite-ai-pod-<variant>:latest

Update Dependencies

# Regenerate pixi lock files
just generate-pixi-locks

# Commit updated locks
git add pods/*/pixi.lock
git commit -m "Chore: Update pixi lock files"

Troubleshooting

Build Fails: "No space left"

# Clean podman storage
podman system prune -a

# Or clean specific images
podman rmi $(podman images -q)

Build Fails: "Permission denied"

Ensure you're running as your user, not root:

# Check
whoami

# Should NOT be root

Cache Not Working

# Force no-cache rebuild
just rebuild-pod my-tag none

Documentation Build Fails

# Install dependencies
pixi install

# Check mkdocs config
mkdocs build --strict

See Also