Skip to content

Making your own Bazzite, Beyond, or Bluefin

Sometimes you don't want to make a whole new image from scratch, you just want to change some things without too much extra work. Sometimes it's nicer to derive from images that more end-user focused like Bazzite, Beyond, and Bluefin.

Use Cases

  • You want to help development by being able to test your contributions prior to submiting to the community.
    • Hardware enablement, experimental features, confirming fixes ahead of merge
  • You want to change out applications and other default choices but want to stick close to Bazzite/Bluefin to get improvements automatically
    • For example, Bluefin DX has Visual Studio baked into the image. If you want the rest of it but don't use vscode you could replace it or remove it.
    • You need to layer something like VPN software that has to be on an image but you don't want to maintain your own standalone image. (Deriving off of others is always easier, that's why we made this project)
    • You want a personal-use image with config and software changes, but also want to benefit from work being completed upstream.

ublue-os/main are used to generate base images of everything, so are usually not good candidates for this unless you are familiar with git, containers, and GitHub Actions. Check out the Setup Guide if you are interested in generating something from a base image.


  1. Fork bazzite/bluefin into your own repo
  2. Install: to your repo and read the docs, be sure to also star the repo for higher priority merging by the bot.
  3. Follow the instructions for generating a new cosign keypair. Ensure that the SIGNING_SECRET and file are in the proper places and that your build succeeds before moving on!
  4. The config file for the pull app is stored at .github/pull.yml, by default it will merge future changes from ublue-os upstream. If you're forking a fork, be sure to change the upstream definition in the config.
  5. Make your changes:
  6. Usually changing package choices, commit them in your repo
  7. The bot will create pull requests for your fork as upstream receives changes, and later merge those pull requests automatically, kicking off an automatic build of your forked image.
  8. Check the actions tab to monitor the build. Then rebase to your personal image. The package name and URL will be in your packages section of github, like this:
  9. Neat huh? Tell your friends how cool this is.


If you are a contributor or want to become one in the future, it could be handy to use a more advanced approach. You will have the best of both worlds: being able to contribute to the upstream project and use your own changes.

The following example is based on the bluefin project.

  1. Create a second branch on your fork called bluefin-main
  2. Change the .github/pull.yml on your main branch to keep bluefin-main in sync with the upstream branch and merge it with your main branch of your fork. Like in the following example:
    version: "1"
      - base: bluefin-main
        upstream: ublue-os:main
        mergeMethod: hardreset
        mergeUnstable: false
      - base: main
        upstream: bluefin-main
        mergeMethod: merge
        mergeUnstable: false
    label: ":arrow_heading_down: pull"
    conflictLabel: "merge-conflict"

Ensuring proper image metadata

Ublue-update and

When forking to create your own image, or using Bluefin as a base image be aware to use the correct values for This script is used to create a file that lives in the container image called image-info.json. An example of that file in bluefin-dx shown below stored in /usr/share/ublue-os/image-info.json:

  "image-name": "bluefin-dx",
  "image-flavor": "main",
  "image-vendor": "ublue-os",
  "image-ref": "ostree-image-signed:docker://",
  "base-image-name": "",
  "fedora-version": "38"

This information is used by the ublue-update service, to get unverified installations to automatically rebase to ostree-image-signed versions. It is also used by the offline ISO to rebase from a local image to the correct remote one. When you create your own image based on Bluefin, or fork these information must be set up correctly to use your fork. The uses variables in the Containerfile to write the correct information into the json file.

  "image-name": "$IMAGE_NAME",
  "image-flavor": "$IMAGE_FLAVOR",
  "image-vendor": "$IMAGE_VENDOR",
  "image-ref": "$IMAGE_REF",
  "base-image-name": "$BASE_IMAGE_NAME",
  "fedora-version": "$FEDORA_MAJOR_VERSION"

So make sure your Container file has the following in it:

A copy of the script to help generate the image-info.json file

COPY /tmp/

A command to run the script

RUN /tmp/

Be sure that the variables used in the script are set to the right values.


All the variables are passed in via build arguments of the container. And should be good to go on a normal fork.

When something goes wrong, double check the values in /usr/share/ublue-os/image-info.json. If you think it is all setup correctly, but still encounter problems? Please let us know by filing an issue and in the mean time disable the service with systemctl disable ublue-update.timer.