Mastodon Skip to content

Building on Universal Blue

Universal Blue is a community project that builds custom images based on atomic Fedora desktops. In addition to their more end-user focused images, the project offers a vast selection of base images with different desktop environments and support for different hardware. Universal Blue base images are the default/recommended base images for custom images built with BlueBuild.

Universal Blue’s base images contain small improvements over the standard Fedora base images, like hardware acceleration, codecs, and including distrobox in addition to toolbx (see list of all packages here). The images also contain some default configuration for enabling automatic updates, udev rules for extended peripheral support, and a set of handy just recipes for system management accessible using the ujust command.

Installing an image based on Universal Blue

Fresh install from an ISO

You can use JasonN3’s build-container-installer to generate an offline ISO of your image locally. See the project’s README for more information it and its configuration. This procedure only requires either podman or docker be installed.

  1. Generate the ISO:

    • With podman:

      Terminal window
      # iso command:
      mkdir ./iso-output
      sudo podman run --rm --privileged --volume ./iso-output:/build-container-installer/build --security-opt label=disable --pull=newer \
      ghcr.io/jasonn3/build-container-installer:latest \
      # iso config:
      IMAGE_REPO=ghcr.io/octocat \
      IMAGE_NAME=weird-os \
      IMAGE_TAG=latest \
      VARIANT=Silverblue # should match the variant your image is based on
    • With docker:

      Terminal window
      # iso command:
      mkdir ./iso-output
      sudo docker run --rm --privileged --volume ./iso-output:/build-container-installer/build --pull=always \
      ghcr.io/jasonn3/build-container-installer:latest \
      # iso config:
      IMAGE_REPO=ghcr.io/octocat \
      IMAGE_NAME=weird-os \
      IMAGE_TAG=latest \
      VARIANT=Silverblue # should match the variant your image is based on
  2. Flash the ISO onto a USB drive (Fedora Media Writer is recommended) and boot it, or boot it directly with a virtual machine.

    • The ISO file should be in a directory called iso-output inside your working directory and called something like deploy.iso.

    • Once booted, you should be presented with a screen similar to this:

  3. Complete the installation by completing all steps and following the installer’s instructions.

    • Dual booting is only possible when using separate disks or doing manual partitioning (unsupported).

By rebasing from an existing installation of Fedora atomic (or a derivative)

If you have already installed an atomic Fedora version or something derivative such as an Universal Blue image, it is possible to switch to another image such as your custom image by just running the commands below:

  1. Rebase to an unsigned image to get the proper signing keys and policies installed:

    Terminal window
    # example image details:
    IMAGE_PATH=ghcr.io/octocat/weird-os
    IMAGE_TAG=latest
    # rebase command:
    rpm-ostree rebase ostree-unverified-registry:$IMAGE_PATH:$IMAGE_TAG
    # reboot to complete the rebase:
    systemctl reboot
  2. Rebase to a signed image to complete the installation:

    Terminal window
    # example image details:
    IMAGE_PATH=ghcr.io/octocat/weird-os
    IMAGE_TAG=latest
    # rebase command:
    rpm-ostree rebase ostree-image-signed:docker://$IMAGE_PATH:$IMAGE_TAG
    # reboot to complete the rebase:
    systemctl reboot

Essential modules

Custom just recipes

Universal Blue provides a set of handy just recipes for system management accessible using the ujust command. It is possible for a custom image maintainer to extend this set of recipes for the purposes of their image.

To get started, create the file /usr/share/ublue-os/just/60-custom.just.

  • This file will contain your custom just recipes.
  • You can copy this file in place with the files module, either by directly copying only the file or by copying the whole usr directory.

You should read the just manual for instructions on writing justfiles.

  • The overall syntax should be very straightforward. Here’s an example:

    60-custom.just
    recipename:
    echo "This is my recipe"
    echo "I can run commands here"
  • By default, each line is run separately. To run a recipe like a script, add the shebang at the beginning of the script to run it with the right interpreter. Here’s an example of a recipe that contains a multi-line bash script:

    60-custom.just
    scriptrecipe:
    #!/usr/bin/env bash
    set -euxo pipefail
    VAR="Hello, world!"
    echo $VAR # Hello, world!

Many of Universal Blue’s default recipes use dialogs to confirm or select the specific changes to be done. Universal Blue uses a wrapper on top of gum and some other tools called ugum as the main way to display these dialogs. It is recommended to add gum to your image and just use it directly, if you want to add dialogs to your custom recipes.