Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

aurora-base-image

Personal Aurora DX images, built from one Containerfile:

Image Machine Base
ghcr.io/wisehalvdan/aurora-base-image Dell laptop (Intel) aurora-dx:stable
ghcr.io/wisehalvdan/aurora-base-image-nvidia Desktop (RTX 3090) aurora-dx-nvidia-open:stable

Shared changes go in build_files/shared/, per-machine changes in build_files/variants/, config files in system_files/.

Waydroid

Both images include Waydroid from Fedora and waydroid-helper from its upstream COPR. Updates arrive through image rebuilds; the COPR is disabled after installation.

After booting the updated image, launch Waydroid in a Plasma Wayland session and initialize Android using the upstream OTA URLs: https://ota.waydro.id/system and https://ota.waydro.id/vendor. Then enable the container service:

sudo systemctl enable --now waydroid-container.service
waydroid show-full-ui

Open Waydroid Helper to configure Android and install optional extensions such as ARM translation. Android images and app data are initialized per machine and persist across OS image updates.

For the NVIDIA desktop, follow the upstream software rendering instructions: add ro.hardware.gralloc=default and ro.hardware.egl=swiftshader under [properties] in /var/lib/waydroid/waydroid.cfg, then run sudo waydroid upgrade -o. Software rendering is slower than GPU acceleration.

Vicinae launcher

Both images include Vicinae from the COPR listed in the Linux installation guide, plus Node.js for extensions. Updates arrive through image rebuilds; the COPR is disabled after installation.

Following the KDE setup guide, the vicinae.service user unit is enabled globally and starts with each Plasma session after booting the updated image. No separate KDE Autostart entry is needed. Check it with systemctl --user status vicinae.service and view logs with journalctl --user -u vicinae.service.

In System Settings → Keyboard → Shortcuts, add a command shortcut for vicinae toggle and choose your preferred keys. For example, to use Alt+Space, first remove that binding from KRunner. Existing shortcuts are preserved by the image.

Vicinae supports KDE Wayland blur directly. If its window does not receive focus, set System Settings → Window Management → Window Behavior → Focus → Focus stealing prevention to Low, as recommended upstream.

RustDesk unattended Wayland access

Both images include the latest upstream RustDesk unattended Wayland preview and its private DRM capture library. The root rustdesk-drm.service starts at boot; open RustDesk to configure your server and unattended-access credentials per machine. No credentials are included in the image.

This is the binary from the official preview, repackaged into the image, not a Fedora RPM or a source build. The September 27, 2026 asset was tested on Aurora 44 with an RTX 3090: desktop access and access at the Plasma Login Manager after reboot both worked. Intel hardware remains untested. build_files/shared/60-rustdesk.sh selects the newest uploaded unattended-Wayland x86_64 Debian asset from the nightly release and verifies its published SHA-256. The selected asset metadata is saved in the image at /usr/share/aurora-base-image/rustdesk-nightly-asset.json.

Each just build refreshes this selection, including builds run by CI. When calling podman build directly, use --no-cache or a fresh --build-arg IMAGE_BUILD_NONCE=.... RustDesk updates arrive with image updates; it does not replace itself on the running system. New nightlies can introduce regressions beyond what the build's library and service checks can detect.

Moving from the temporary system extension

On the desktop used for testing, remove the extension before booting this image so its older files and /etc service do not override the image installation. From a local terminal or SSH (this stops RustDesk until the new image boots):

sudo ~/rustdesk-drm/remove.sh

Then switch to the built image and reboot. RustDesk user settings are preserved. No system extension or local RPM layering is needed on the new image. Check the service with systemctl status rustdesk-drm.service.

Per-machine setup after install

NetBird: both images include the daemon, desktop app, and its GTK/WebKit dependencies from the official installation instructions. The netbird.service is enabled at boot. Open NetBird to enroll each machine, or run sudo netbird up (add --management-url https://your-server for a self-hosted deployment). Credentials and device identity are not baked into the image. NetBird updates arrive through image rebuilds; its RPM repository is disabled outside the build transaction.

Wireshark capture without root: add yourself to the wireshark group, then log out and back in:

sudo usermod -aG wireshark "$USER"

Flatpaks listed in system_files/usr/share/flatpak/preinstall.d/ install on first boot.

Homebrew packages listed in system_files/usr/share/aurora-base-image/Brewfile are installed once, after first login:

brew bundle --file=/usr/share/aurora-base-image/Brewfile

Template documentation

This repository is meant to be a template for building your own custom bootc image. This template is the recommended way to make customizations to any image published by the Universal Blue Project.

Community

If you have questions about this template after following the instructions, try the following spaces:

How to Use

To get started on your first bootc image, simply read and follow the steps in the next few headings. If you prefer instructions in video form, TesterTech created an excellent tutorial, embedded below.

Video Tutorial

Step 0: Prerequisites

These steps assume you have the following:

  • A Github Account
  • A machine running a bootc image (e.g. Bazzite, Bluefin, Aurora, or Fedora Atomic)
  • Experience installing and using CLI programs

Step 1: Preparing the Template

Step 1a: Copying the Template

Select Use this Template on this page. You can set the name and description of your repository to whatever you would like, but all other settings should be left untouched.

Once you have finished copying the template, you need to enable the Github Actions workflows for your new repository. To enable the workflows, go to the Actions tab of the new repository and click the button to enable workflows.

Step 1b: Cloning the New Repository

Here I will defer to the much superior GitHub documentation on the matter. You can use whichever method is easiest. GitHub Documentation

Once you have the repository on your local drive, proceed to the next step.

Step 2: Initial Setup

Step 2a: Creating a Cosign Key

Container signing is important for end-user security and is enabled on all Universal Blue images. By default the image builds will fail if you don't.

First, install the cosign CLI tool With the cosign tool installed, run inside your repo folder:

COSIGN_PASSWORD="" cosign generate-key-pair

The signing key will be used in GitHub Actions and will not work if it is password protected.

Warning

Be careful to never accidentally commit cosign.key into your git repo. If this key goes out to the public, the security of your repository is compromised.

Next, you need to add the key to GitHub. This makes use of GitHub's secret signing system.

Using the Github Web Interface (preferred)

Go to your repository settings, under Secrets and Variables -> Actions image Add a new secret and name it SIGNING_SECRET, then paste the contents of cosign.key into the secret and save it. Make sure it's the .key file and not the .pub file. Once done, it should look like this: image

Using the Github CLI

If you have the github-cli installed, run:

gh secret set SIGNING_SECRET < cosign.key

Step 2b: Choosing Your Base Image

To choose a base image, simply modify the line in the container file starting with FROM. This will be the image your image derives from, and is your starting point for modifications. For a base image, you can choose any of the Universal Blue images or start from a Fedora Atomic system. Below this paragraph is a dropdown with a non-exhaustive list of potential base images.

Base Images
  • Bazzite: ghcr.io/ublue-os/bazzite:stable
  • Aurora: ghcr.io/ublue-os/aurora:stable
  • Bluefin: ghcr.io/ublue-os/bluefin:stable
  • Universal Blue Base: ghcr.io/ublue-os/base-main:latest
  • Fedora: quay.io/fedora/fedora-bootc:44

You can find more Universal Blue images on the packages page.

If you don't know which image to pick, choosing the one your system is currently on is the best bet for a smooth transition. To find out what image your system currently uses, run the following command:

sudo bootc status

This will show you all the info you need to know about your current image. The image you are currently on is displayed after Booted image:. Paste that information after the FROM statement in the Containerfile to set it as your base image.

Step 2c: Changing Names

Change the IMAGE_NAME and REPO_ORGANIZATION variable inside the image-template.env

To commit and push all the files changed and added in step 2 into your Github repository:

git add Containerfile image-template.env cosign.pub
git commit -m "Initial Setup"
git push

Once pushed, go look at the Actions tab on your Github repository's page. The green checkmark should be showing on the top commit, which means your new image is ready!

Step 3: Switch to Your Image

From your bootc system, run the following command substituting in your Github username and image name where noted.

sudo bootc switch ghcr.io/<username>/<image_name>

This should queue your image for the next reboot, which you can do immediately after the command finishes. You have officially set up your custom image! See the following section for an explanation of the important parts of the template for customization.

Repository Contents

Containerfile

The Containerfile defines the operations used to customize the selected image.This file is the entrypoint for your image build, and works exactly like a regular podman Containerfile. For reference, please see the Podman Documentation.

build.sh

The build.sh file is called from your Containerfile. It is the best place to install new packages or make any other customization to your system. There are customization examples contained within it for your perusal.

build.yml

The build.yml Github Actions workflow creates your custom OCI image and publishes it to the Github Container Registry (GHCR). By default, the image name will match the Github repository name.

Building Disk Images

This template provides an out of the box workflow for creating disk images (ISO, qcow, raw) for your custom OCI image which can be used to directly install onto your machines.

This template provides a way to upload the disk images that is generated from the workflow to a S3 bucket. The disk images will also be available as an artifact from the job, if you wish to use an alternate provider. To upload to S3 we use rclone which is able to use many S3 providers.

Setting Up ISO Builds

The build-disk.yml Github Actions workflow creates a disk image from your OCI image by utilizing the bootc-image-builder. In order to use this workflow you must complete the following steps:

  1. Modify disk_config/iso.toml to point to your custom container image before generating an ISO image.
  2. If you changed your image name from the default in build.yml then in the build-disk.yml file edit the IMAGE_REGISTRY, IMAGE_NAME and DEFAULT_TAG environment variables with the correct values. If you did not make changes, skip this step.
  3. Finally, if you want to upload your disk images to S3 then you will need to add your S3 configuration to the repository's Action secrets. This can be found by going to your repository settings, under Secrets and Variables -> Actions. You will need to add the following
  • S3_PROVIDER - Must match one of the values from the supported list
  • S3_BUCKET_NAME - Your unique bucket name
  • S3_ACCESS_KEY_ID - It is recommended that you make a separate key just for this workflow
  • S3_SECRET_ACCESS_KEY - See above.
  • S3_REGION - The region your bucket lives in. If you do not know then set this value to auto.
  • S3_ENDPOINT - This value will be specific to the bucket as well.

Once the workflow is done, you'll find the disk images either in your S3 bucket or as part of the summary under Artifacts after the workflow is completed.

Artifacthub

This template comes with the necessary tooling to index your image on artifacthub.io. Use the artifacthub-repo.yml file at the root to verify yourself as the publisher. This is important to you for a few reasons:

  • The value of artifacthub is it's one place for people to index their custom images, and since we depend on each other to learn, it helps grow the community.
  • You get to see your pet project listed with the other cool projects in Cloud Native.
  • Since the site puts your README front and center, it's a good way to learn how to write a good README, learn some marketing, finding your audience, etc.

Discussion Thread

Justfile Documentation

The Justfile contains various commands and configurations for building and managing container images and virtual machine images using Podman and other utilities. It is also used inside Github Actions.

Required Utilities

Container build:

These are usually preinstalled on Universal Blue's Bootc Images.

Linting:

  • shfmt
  • shellcheck

Environment Variables

These are all sourced from the image-template.env file.

  • image_name: The name of the image (default: "image-template").
  • default_tag: The default tag for the image (default: "latest").
  • bib_image: The Bootc Image Builder (BIB) image (default: "quay.io/centos-bootc/bootc-image-builder:latest").

Building The Image

All these recipes will work (with default values) without supplying any arguments to them, e.g. just build

just build

Builds a container image using Podman.

just build $target_image $tag

Arguments:

  • $target_image: The tag you want to apply to the image (default: $image_name).
  • $tag: The tag for the image (default: $default_tag).

Rechunking

We can flatten the layers of container images to make sure there isn't a single huge layer when your image gets published. This does not make your image faster to download, just provides better resumability.

just ostree-rechunk

Rechunks the existing Image with rpm-ostree

just ostree-rechunk $target_image $tag

just rechunk

Rechunks the existing Image with chunkah, this is probably gonna be the default here at some point, try it out, it's cool.

just rechunk $target_image $tag

Switching to the locally built image for testing

The image has to be in the containers-storage owned by root, to be able to rebase to it, see the _rootful_load_image recipe.

sudo just build and sudo just ostree-rechunk builds directly as root and allows you to skip the transfer to the root containers-storage.

You can rebase to all the images that are in your containers-storage:

sudo podman image list --filter=label=containers.bootc=1

See man bootc switch for more info.

sudo bootc switch --transport containers-storage localhost/myimage:latest

and reboot your system!

Building and Running Virtual Machines and ISOs

The below commands all build QCOW2 images. To produce or use a different type of image, substitute in the command with that type in the place of qcow2. The available types are qcow2, iso, and raw.

just build-qcow2

Builds a QCOW2 virtual machine image.

just build-qcow2 $target_image $tag

just rebuild-qcow2

Rebuilds a QCOW2 virtual machine image.

just rebuild-vm $target_image $tag

just run-vm-qcow2

Runs a virtual machine from a QCOW2 image.

just run-vm-qcow2 $target_image $tag

just spawn-vm

Runs a virtual machine using systemd-vmspawn.

just spawn-vm rebuild="0" type="qcow2" ram="6G"

File Management

just check

Checks the syntax of all .just files and the Justfile.

just fix

Fixes the syntax of all .just files and the Justfile.

just clean

Cleans the repository by removing build artifacts.

just lint

Runs shell check on all Bash scripts.

just format

Runs shfmt on all Bash scripts.

Additional resources

For additional driver support, ublue maintains a set of scripts and container images available at ublue-akmod. These images include the necessary scripts to install multiple kernel drivers within the container (Nvidia, OpenRazer, Framework...). The documentation provides guidance on how to properly integrate these drivers into your container image.

Community Examples

These are images derived from this template (or similar enough to this template). Reference them when building your image!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages