ublue-os image-template

repository·main·Indexed 21 days ago

https://github.com/ublue-os/image-template

A template for building custom bootc-based OCI images optimized for the Universal Blue ecosystem. It provides automated workflows for building, signing with Cosign, and distributing custom Linux images. The template supports creating installable disk images (ISO, qcow, raw) via bootc-image-builder and includes a Justfile for managing container builds, VM image generation, and linting.

Tokens
1.8K
Snippets
9
Records
12
Agent score
24%

What's inside ublue-os-image-template

  1. Set up ISO/Disk image builds with S3 upload

    main

    The build-disk.yml workflow uses bootc-image-builder to create installable disk images (ISO, qcow, raw). To enable automatic upload to an S3 bucket, add the following secrets to your GitHub repository (Settings -> Secrets and Variables -> Actions):

    • S3_PROVIDER: An rclone-compatible S3 provider name.
    • S3_BUCKET_NAME: Your target bucket name.
    • S3_ACCESS_KEY_ID: Your S3 access key.
    • S3_SECRET_ACCESS_KEY: Your S3 secret key.
    • S3_REGION: The bucket region (use auto if unknown).
    • S3_ENDPOINT: The specific endpoint for your bucket.

    Note: If you changed your image name from the default, you must also update IMAGE_REGISTRY, IMAGE_NAME, and DEFAULT_TAG in the .github/workflows/build-disk.yml file, and ensure disk_config/iso.toml points to your custom container image.

  2. Create a custom bootc image from the template

    main

    To build your own custom bootc image using this template, follow these high-level steps:

    1. Prepare the Template: Use the Use this template feature on GitHub to create your own repository. Enable GitHub Actions in the Actions tab of your new repository.
    2. Clone the Repository: Clone your new repository to your local machine.
    3. Initial Setup:
      • Generate a Cosign Key: Create a signing key for container security. This is required for builds to succeed.
      • Configure Base Image: Modify the FROM line in the Containerfile to select your starting point (e.g., Bazzite, Bluefin, or Fedora Atomic).
      • Set Identity: Update IMAGE_NAME and REPO_ORGANIZATION in image-template.env.
    4. Build and Switch: Once GitHub Actions completes the build, use bootc switch on your target machine to transition to your new image.
    # Example: Switching to your new image
    sudo bootc switch ghcr.io/<username>/<image_name>
  3. Switch to a locally built image for testing

    main

    To test a locally built image, it must reside in the containers-storage owned by root so you can rebase to it.

    Tip: Running sudo just build or sudo just ostree-rechunk builds directly as root, which allows you to skip the manual transfer to the root containers-storage.

    To find images available for rebasing:

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

    To switch your system to the local image, use bootc switch and then reboot:

    sudo bootc switch --transport containers-storage localhost/myimage:latest
  4. Choose and configure a base image

    main

    The Containerfile uses a FROM instruction to define the base image. You can choose from various Universal Blue images or standard Fedora Atomic images.

    Common 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

    To identify your current system's base image, run:

    sudo bootc status

    Look for the value after Booted image: and use that in your Containerfile.

  5. Configure container signing with Cosign

    main

    Container signing is mandatory for Universal Blue images. Builds will fail if a signing key is not provided via GitHub Secrets.

    1. Generate Key Pair: Run the following command in your repository folder. Use an empty password so GitHub Actions can use it without interaction.
    2. Add to GitHub: Add the contents of cosign.key (the private key) to your GitHub repository secrets as SIGNING_SECRET.

    WARNING: Never commit cosign.key to your git repository. Only commit cosign.pub.

    # Generate key pair with no password
    COSIGN_PASSWORD="" cosign generate-key-pair
    
    # Alternatively, using GitHub CLI to set the secret
    gh secret set SIGNING_SECRET < cosign.key
  6. Configure identity in image-template.env

    main

    To ensure your image is built and published with the correct names, you must update the image-template.env file with your specific identifiers:

    • IMAGE_NAME: The name of your custom image.
    • REPO_ORGANIZATION: Your GitHub username or organization name.

    After updating, commit and push the changes to trigger the GitHub Actions build.

    # After editing image-template.env, commit your changes
    git add Containerfile image-template.env cosign.pub
    git commit -m "Initial Setup"
    git push
  7. Reference: image-template.env variables

    main

    The following environment variables are sourced from image-template.env and are used by the Justfile and GitHub Actions workflows:

    • 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).
  8. Build and run Virtual Machine images (QCOW2, ISO, RAW)

    main

    The template provides recipes for building and running VM images. While the examples below use qcow2, you can substitute the command with iso or raw to produce different image types.

    Build/Rebuild QCOW2:

    • just build-qcow2 $target_image $tag
    • just rebuild-qcow2 $target_image $tag

    Run QCOW2:

    • just run-vm-qcow2 $target_image $tag

    Run via systemd-vmspawn:

    just spawn-vm rebuild="0" type="qcow2" ram="6G"
    just build-qcow2 $target_image $tag
    just rebuild-qcow2 $target_image $tag
    just run-vm-qcow2 $target_image $tag
    just spawn-vm rebuild="0" type="qcow2" ram="6G"
  9. Rechunk an existing image for better resumability

    main

    Rechunking flattens the layers of container images to prevent a single massive layer from being published. This improves download resumability without increasing download speed.

    You can rechunk using either rpm-ostree or chunkah.

    Using rpm-ostree:

    just ostree-rechunk $target_image $tag

    Using chunkah:

    just rechunk $target_image $tag
    just ostree-rechunk $target_image $tag
    # OR
    just rechunk $target_image $tag
  10. Manage repository files and linting

    main

    Use the following just commands to maintain the repository and ensure script quality:

    • 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: Removes build artifacts.
    • just lint: Runs shellcheck on all Bash scripts.
    • just format: Runs shfmt on all Bash scripts.
    just check
    just fix
    just clean
    just lint
    just format
  11. Build a container image with `just build`

    main

    Use the just build command to build a container image using Podman. By default, it uses the $image_name and $default_tag defined in your configuration. You can optionally provide specific arguments for the target image and 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).
    just build $target_image $tag