BlueForge is the desktop OS I build for myself: secure, practical, and ready for daily dev work from first boot.
It is based on ghcr.io/ublue-os/bluefin:stable, but tuned to my workflow: Ghostty-first terminal behavior, security tools I actually use, and runtime app management that stays simple.
Compared to stock Bluefin, this is the setup my AEC team wants to live in every day. The guiding rule: native dnf/RPM packages wherever possible (clean desktop integration on bootc), Flatpak/AppImage only as a last resort.
Baked into the image so the desktop is usable from first boot:
- Terminal & security: Ghostty, 1Password, Mullvad VPN.
- Browser: Brave Origin (Brave's minimal build; free on Linux) from Brave's official RPM repo.
- Productivity & comms: Bitwarden (vendor RPM), Zoom (vendor RPM), Dropbox (
nautilus-dropboxfrom Dropbox's Fedora repo). - Office suite: LibreOffice (Writer/Calc/Impress/Draw + English langpack + GNOME integration) from Fedora repos, preconfigured to behave like MS Office — see below.
- Why dnf-first: Bitwarden and the browser especially integrate far more cleanly as RPMs than as Flatpaks on a bootc system.
These have no Fedora RPM/dnf repo, so the vendor's official "latest" build is baked into /opt with a system launcher (refreshed on image rebuild):
- Beeper (unified chat) — official AppImage, extracted to
/opt/beeper. - Typora (markdown editor) — official tarball in
/opt/typora. - UpNote (note-taking) — official AppImage, extracted to
/opt/upnote.
These are managed by Homebrew but installed automatically on first login — a
per-user systemd service (blueforge-brew-bundle.service) runs brew bundle over
the curated Brewfiles, so the toolchain is there out of the box with nothing to
type. It re-runs only when the Brewfiles change after an image update, and Bluefin's
brew-upgrade timer keeps installed packages current. The ujust install-* recipes
below remain as manual fallbacks.
- CLI tools (Homebrew):
bat,eza,fd,rg,gh,git,neovim,opencode,claude-code,starship,btop,tmux. - JS/TS toolchain: Vite+ (
vite-plus/vp) — one CLI that manages the Node runtime (pulled in as a dependency, so node/npm come with it), the per-project package manager, and the frontend toolchain (Vite, Vitest, Oxlint, Oxfmt, Rolldown, tsdown).ujust install-codexadds the OpenAI Codex CLI on top (Codex is npm-only — Homebrew'scodexis macOS-only). - GUI apps (Flatpak): Aerion (email), GNOME utilities, Pinta, Clapper, Flatseal, Extension Manager, Mission Center, Warehouse, Ignition, Impression, DistroShelf, Bazaar, Refine, plus GTK theme runtimes.
ujustinstallers for licensed/no-repo apps:ujust install-bricscad [rpm]— layers the account-gated BricsCAD RPM viarpm-ostree. With no argument it auto-detects the newestBricsCAD-*.rpmin~/Downloads. The RPM (~1.1GB) is licensed and stays out of the image/repo; activate with your license key on first launch.ujust install-codex— installs the Codex CLI on its own.
A system-wide config overlay (custom/libreoffice/blueforge-msoffice.xcd) sets:
- Default save formats to Microsoft OOXML:
.docx/.xlsx/.pptx. - Tabbed "Notebookbar" ribbon UI (closest to the MS Office ribbon) for Writer/Calc/Impress/Draw.
- No "keep in MS format?" nag on every save.
Users can still change any of this in Tools > Options. The Navigator side panel (MS Word's "navigation pane" equivalent) toggles with F5.
- Removed:
ptyxis(Ghostty is preferred instead). - Not preinstalled: Firefox Flatpak is intentionally not in defaults (Brave Origin is the default browser).
- Disabled by default: Cosign signing and SBOM attestation stay off until secrets are configured.
- Sets Ghostty as preferred terminal via
/etc/xdg/xdg-terminals.list. - Enables
podman.socketat build time. - Copies and merges custom Brewfiles,
ujustrecipes, Flatpak preinstall manifests, and the LibreOffice config overlay into system locations. - Uses an isolated COPR install for Ghostty to avoid repo persistence.
Last updated: 2026-06-16
BlueForge uses a multi-stage Containerfile:
ctxstage assembles:- local
build/ - local
custom/ ghcr.io/projectbluefin/commonsystem filesghcr.io/ublue-os/brewsystem files
- local
- final stage starts from
ghcr.io/ublue-os/bluefin:stableand runsbuild/10-build.shwith/ctxmounted.
This keeps customization modular and reproducible while staying aligned with Universal Blue conventions.
If I had to describe this OS in one line: Bluefin reliability, but with my defaults already made.
- Security-first without being heavy-handed.
- Terminal-first without abandoning desktop quality-of-life.
- Runtime apps and tooling so iteration stays fast.
- Minimal surprises in day-to-day use.
- You want Bluefin stability with curated defaults.
- You prefer a terminal-first workflow but still want polished desktop UX.
- You want security tools available immediately.
- You want most tools managed at runtime instead of rebaking images constantly.
Containerfile- base image, layered context, and build execution.build/10-build.sh- build-time packages (dnf/RPM +/optapps) and system configuration.custom/brew/*.Brewfile- runtime CLI/dev/font package bundles.custom/flatpaks/default.preinstall- first-boot GUI app manifest.custom/libreoffice/blueforge-msoffice.xcd- system-wide LibreOffice MS-Office-like defaults.custom/ujust/*.just- user-facing app/system helpers..github/workflows/*.yml- CI build, cleanup, Renovate, and validation workflows.
Where to make changes:
- Build-time system changes (dnf/RPM packages,
/optapps, system config): editbuild/10-build.sh. - Runtime CLI tools: edit
custom/brew/default.Brewfileand related Brewfiles. - Runtime GUI apps: edit
custom/flatpaks/default.preinstall. - User shortcuts: edit
custom/ujust/custom-apps.justandcustom/ujust/custom-system.just.
just build
just build-qcow2
just run-vm-qcow2Optional ISO flow:
just build-iso
just run-vm-isoBlueForge publishes two images from this repo:
ghcr.io/sc-frederick/blueforge:stable— standard (no GPU drivers), for machines without an Nvidia dGPU.ghcr.io/sc-frederick/blueforge-nvidia:stable— for Intel + Nvidia dedicated GPU machines. Identical to the standard image plus Nvidia's proprietary akmod drivers (inherited fromghcr.io/ublue-os/bluefin-nvidia:stable).
Standard:
sudo bootc switch ghcr.io/sc-frederick/blueforge:stable
sudo systemctl rebootNvidia:
sudo bootc switch ghcr.io/sc-frederick/blueforge-nvidia:stable
sudo systemctl reboot- Secure Boot: The Nvidia kernel modules are signed with Universal Blue's key
(inherited from the base image). On Secure Boot machines, enroll that key once with
ujust enroll-secure-boot-key(reboot and confirm via the blue MOK enrollment screen), or disable Secure Boot. No signing work is needed in this repo — BlueForge layers on top of the prebuilt Nvidia base and never rebuilds the kernel or akmods, so the signed modules carry through unchanged. - Driver choice: The Nvidia image uses the proprietary driver
(
bluefin-nvidia). Universal Blue is standardizing on the open kernel modules (nvidia-open) for 2026+ and phasing out the closed driver. For Turing / RTX-20-series or newer GPUs, switching toghcr.io/ublue-os/bluefin-nvidia-open:stableis a one-line change to thebase_imagein the.github/workflows/build.ymlmatrix.
BASE_IMAGE=ghcr.io/ublue-os/bluefin-nvidia:stable just build blueforge-nvidia stable
just build-iso-nvidiaSigning is intentionally disabled by default so first builds work immediately.
When ready:
- Generate keys with
cosign generate-key-pair. - Add private key contents to GitHub Actions secret
SIGNING_SECRET. - Commit your real
cosign.pub. - Uncomment signing steps in
.github/workflows/build.yml. - (Optional) Uncomment SBOM generation + attestation steps.
Never commit cosign.key.
The Homebrew toolchain installs itself on first login (see Added Applications above). These commands are manual fallbacks — to re-run a bundle yourself, or to install the optional bundles:
ujust install-default-apps # CLI tools + Vite+ (runs automatically too)
ujust install-dev-tools # optional heavier dev bundle
ujust install-fonts # Nerd Fonts
ujust install-all-brew # all bundles at onceOptional / licensed apps:
ujust install-codex # OpenAI Codex CLI (npm global)
ujust install-bricscad # licensed; auto-detects RPM in ~/DownloadsExtra helpers:
ujust install-jetbrains-toolbox
ujust configure-dev-groups
ujust clean-containers
ujust update-and-rebootPRs run validations for:
- Shell scripts (
shellcheck) - Brewfile syntax
- Flatpak IDs
- Justfile syntax
- Renovate config
Main branch builds and publishes the stable image tags.
- Universal Blue: https://universal-blue.org/
- Bluefin: https://projectbluefin.io
- bootc: https://containers.github.io/bootc/
- Flatpak app IDs: https://flathub.org/