Shared OCI layer containing common configuration files used across all Bluefin variants (bluefin, bluefin-dx, bluefin-lts).
This repository organizes configuration files into two main directories, these are important:
Files specific to Bluefin
- GNOME desktop settings and theming
- Bluefin wallpapers and branding
- Desktop-specific environment variables
- GNOME Initial Setup configuration
Files shared with Aurora — Aurora maintainers can cherry-pick commits touching this directory. Edit directly here; changes propagate to all Bluefin variants on next build.
This includes:
Justrecipes for system management- Brewfiles for application bundles
- Setup hooks (privileged, system, user)
- Container policies and security settings
- MOTD templates and CLI bling
- Common shell configurations
Reference this layer as a build stage and copy the directories you need:
FROM ghcr.io/projectbluefin/common:latest AS bluefin-common
# Copy all system files
COPY --from=bluefin-common /system_files /FROM ghcr.io/projectbluefin/common:latest AS bluefin-common
# Copy only /etc configuration
COPY --from=bluefin-common /system_files/etc /etcFROM ghcr.io/projectbluefin/common:latest AS bluefin-common
# Copy only /usr/share configuration
COPY --from=bluefin-common /system_files/usr /usrBluefin-common provides a comprehensive flatpak customization system with multiple layers:
Default flatpaks are now managed via Homebrew Brewfiles, allowing for declarative system-wide installation:
system-flatpaks.Brewfile- Core flatpaks installed on all Bluefin variants (37 applications including Firefox, Thunderbird, GNOME Circle apps, and utilities)system-dx-flatpaks.Brewfile- Additional development-focused flatpaks for DX mode (6 applications including Podman Desktop, Builder, and DevToolbox)
These can be installed using:
ujust install-system-flatpaksTwo types of flatpak overrides are provided to grant additional permissions to specific applications:
System-level overrides (/usr/share/ublue-os/flatpak-overrides/):
io.github.kolunmi.Bazaar- Grants access tohost-etcfor system configuration
User-level overrides (/etc/skel/.local/share/flatpak/overrides/):
com.visualstudio.code- Enables Wayland support and Podman socket accesscom.google.Chrome- Grants access to local applications and icons directories
These overrides are automatically applied to new user accounts through the /etc/skel template.
Automatic updates are handled by uupd, which updates the system image,
Flatpaks, Distrobox containers, and Homebrew together. To keep image updates
enabled while choosing a different Flatpak cadence, disable only uupd's
Flatpak module.
/etc/uupd/config.json ships on every image — it already sets
modules.distrobox.disable = true — so it always exists and must be edited
with jq, never overwritten with a fresh payload. This snippet refuses to
install an empty or invalid result, so a missing jq or a failed edit cannot
wipe the shipped config:
command -v jq # required; install jq first if this prints nothing
tmp="$(mktemp)"
sudo jq '.modules.flatpak.disable = true' /etc/uupd/config.json >"$tmp" \
&& jq -e . "$tmp" >/dev/null \
&& sudo install -m 0644 "$tmp" /etc/uupd/config.json
rm -f "$tmp"The configuration is read on each uupd run, so it applies to the next
scheduled update. Do not edit /usr/lib/systemd/system/uupd.timer; image
updates replace files there. To change only the schedule, write a drop-in
with sudo systemctl edit uupd.timer, which lives under /etc and survives
image updates.
After disabling the module, create local systemd service and timer units under
/etc/systemd/system (or user units under ~/.config/systemd/user) that run
flatpak update --system --noninteractive and/or
flatpak update --user --noninteractive at the cadence you want. For example,
this system-wide timer runs Flatpak updates every 60 days:
# /etc/systemd/system/flatpak-system-update.service
[Unit]
Description=Update system Flatpaks
[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak update --system --noninteractive# /etc/systemd/system/flatpak-system-update.timer
[Timer]
OnBootSec=15min
OnUnitActiveSec=60d
Persistent=true
[Install]
WantedBy=timers.targetEnable it with sudo systemctl daemon-reload and
sudo systemctl enable --now flatpak-system-update.timer. Keep custom units
under /etc or ~/.config so they survive image updates. Set
modules.flatpak.disable to false or remove it to return Flatpak updates to
the normal uupd.timer schedule.
The /usr/share/ublue-os/homebrew/ directory contains curated application bundles installable via bbrew:
system-flatpaks.Brewfile- Default system-wide flatpaks for all Bluefin variantssystem-dx-flatpaks.Brewfile- Additional flatpaks for DX (Developer Experience) modefull-desktop.Brewfile- Comprehensive collection of GNOME Circle and community flatpak applications for a full desktop experiencefonts.Brewfile- Common fonts for everyday workfonts-dev.Brewfile- Additional monospace fonts for developmentcli.Brewfile- CLI tools and utilitiesai-tools.Brewfile- AI and machine learning toolscncf.Brewfile- Cloud Native Computing Foundation toolsk8s-tools.Brewfile- Kubernetes toolside.Brewfile- Integrated development environmentsartwork.Brewfile- Design and artwork applications
Users can install these bundles using the ujust bbrew command, which will prompt them to select a Brewfile.
The local Bluespeed stack can be installed directly with ujust bluespeed.
Changes are validated in three layers:
If you need the per-workflow purpose and ownership map, start with
docs/skills/workflow-map.md.
On every PR:
validate.yml—just check, shellcheck, pre-commit, submodule drift, registry/dconf guardsbuild.yml— builds the OCI image withbuildahskill-drift.yml— warns when implementation changes land without matching skill-doc updatespr-e2e.yml— advisory composed-image common-suite check against a downstream Bluefin base
On merge to main — full layer validation via projectbluefin/testsuite:
- Runs the
commonbehave suite against Bluefin LTS, Bluefin Stable, and Dakota - SSH-mode: behave runs from the GHA runner over SSH into a QEMU VM — no full GNOME session needed, completes in ~15 min
- Validates dconf defaults, locked keys,
ujust, setup scripts, desktop entries, and shell configuration as they land in the composed images
Before downstream testing → stable promotions:
promotion-candidate-e2e.ymlrunssmoke,commonagainstghcr.io/projectbluefin/bluefin:{testing,lts-testing}on Tuesdays, givingcommona repo-local signal on the exact candidate tags that feed promotion
just build