A template for building custom bootc operating system images based on the lessons from Universal Blue and Bluefin. It is designed to be used manually, but is optimized to be bootstraped by GitHub Copilot. After set up you'll have your own custom Linux.
Be the one who moves, not the one who is moved.
Here are the steps to guide copilot to make your own repo, or just use it like a regular image template.
- Click the green "Use this as a template" button and create a new repository
- Select your owner, pick a repo name for your OS, and a description
- In the "Jumpstart your project with Copilot (optional)" add this, modify to your liking:
Use @castrojo/finpilot as a template, name the OS the repository name. Ensure the entire operating system is bootstrapped. Ensure all github actions are enabled and running. Ensure the README has the github setup instructions for cosign and the other steps required to finish the task.
- Automated builds via GitHub Actions on every commit
- Awesome self hosted Renovate setup that keeps all your images and actions up to date.
- Automatic cleanup of old images (90+ days) to keep it tidy
- Pull request workflow - test changes before merging to main
- PRs build and validate before merge
mainbranch builds:stableimages
- Validates your files on pull requests so you never break a build:
- Brewfile, Justfile, ShellCheck, Renovate config, and it'll even check to make sure the flatpak you add exists on FlatHub
- Production Grade Features
- Container signing, SBOM Generation, and layer rechunking.
- See checklist below to enable these as they take some manual configuration
- Pre-configured Brewfiles for easy package installation and customization
- Includes curated collections: development tools, fonts, CLI utilities. Go nuts.
- Users install packages at runtime with
brew bundle, aliased to premadeujust commands - See custom/brew/README.md for details
- Ship your favorite flatpaks
- Automatically installed on first boot after user setup
- See custom/flatpaks/README.md for details
- Optimizes container image layer distribution for better download resumability
- Based on hhd-dev/rechunk v1.2.4
- Disabled by default for faster initial builds
- Enable in
.github/workflows/build.ymlby uncommenting the rechunker steps (see comments in file) - Recommended for production deployments after initial testing
- User-friendly command shortcuts via
ujust - Pre-configured examples for app installation and system maintenance for you to customize
- See custom/ujust/README.md for details
- Modular numbered scripts (10-, 20-, 30-) run in order
- Example scripts included for third-party repositories and desktop replacement
- Helper functions for safe COPR usage
- See build/README.md for details
Click "Use this template" to create a new repository from this template.
Important: Change finpilot to your repository name in these 5 files:
Containerfile(line 9):# Name: your-repo-nameJustfile(line 1):export image_name := "your-repo-name"README.md(line 1):# your-repo-nameartifacthub-repo.yml(line 5):repositoryID: your-repo-namecustom/ujust/README.md(~line 175):localhost/your-repo-name:stable
- Go to the "Actions" tab in your repository
- Click "I understand my workflows, go ahead and enable them"
Your first build will start automatically!
Note: Image signing is disabled by default. Your images will build successfully without any signing keys. Once you're ready for production, see "Optional: Enable Image Signing" below.
Choose your base image in Containerfile (line 23):
FROM ghcr.io/ublue-os/bluefin:stableAdd your packages in build/10-build.sh:
dnf5 install -y package-nameCustomize your apps:
- Add Brewfiles in
custom/brew/(guide) - Add Flatpaks in
custom/flatpaks/(guide) - Add ujust commands in
custom/ujust/(guide)
All changes should be made via pull requests:
- Open a pull request on GitHub with the change you want.
- The PR will automatically trigger:
- Build validation
- Brewfile, Flatpak, Justfile, and shellcheck validation
- Test image build
- Once checks pass, merge the PR
- Merging triggers publishes a
:stableimage
Switch to your image:
sudo bootc switch ghcr.io/your-username/your-repo-name:stable
sudo systemctl rebootImage signing is disabled by default to let you start building immediately. However, signing is strongly recommended for production use.
- Verify image authenticity and integrity
- Prevent tampering and supply chain attacks
- Required for some enterprise/security-focused deployments
- Industry best practice for production images
- Generate signing keys:
cosign generate-key-pairThis creates two files:
cosign.key(private key) - Keep this secretcosign.pub(public key) - Commit this to your repository
-
Add the private key to GitHub Secrets:
- Copy the entire contents of
cosign.key - Go to your repository on GitHub
- Navigate to Settings → Secrets and variables → Actions (GitHub docs)
- Click "New repository secret"
- Name:
SIGNING_SECRET - Value: Paste the entire contents of
cosign.key - Click "Add secret"
- Copy the entire contents of
-
Replace the contents of
cosign.pubwith your public key:- Open
cosign.pubin your repository - Replace the placeholder with your actual public key
- Commit and push the change
- Open
-
Enable signing in the workflow:
- Edit
.github/workflows/build.yml - Find the "OPTIONAL: Image Signing with Cosign" section.
- Uncomment the steps to install Cosign and sign the image (remove the
#from the beginning of each line in that section). - Commit and push the change
- Edit
-
Your next build will produce signed images!
Important: Never commit cosign.key to the repository. It's already in .gitignore.
Ready to take your custom OS to production? Enable these features for enhanced security, reliability, and performance:
-
Enable Image Signing (Recommended)
- Provides cryptographic verification of your images
- Prevents tampering and ensures authenticity
- See "Optional: Enable Image Signing" section above for setup instructions
- Status: Disabled by default to allow immediate testing
-
Enable Rechunker (Recommended)
- Optimizes image layer distribution for better download resumability
- Improves reliability for users with unstable connections
- To enable:
- Edit
.github/workflows/build.yml - Find the "Rechunk (OPTIONAL)" section around line 121
- Uncomment the "Run Rechunker" step
- Uncomment the "Load in podman and tag" step
- Comment out the "Tag for registry" step that follows
- Commit and push
- Edit
- Status: Disabled by default for faster initial builds
-
Enable SBOM Attestation (Recommended)
- Generates Software Bill of Materials for supply chain security
- Provides transparency about what's in your image
- Requires image signing to be enabled first
- To enable:
- First complete image signing setup above
- Edit
.github/workflows/build.yml - Find the "OPTIONAL: SBOM Attestation" section around line 232
- Uncomment the "Add SBOM Attestation" step
- Commit and push
- Status: Disabled by default (requires signing first)
Your workflow will:
- Sign all images with your key
- Generate and attach SBOMs
- Optimize layers for better distribution
- Provide full supply chain transparency
Users can verify your images with:
cosign verify --key cosign.pub ghcr.io/your-username/your-repo-name:stable- Homebrew/Brewfiles - Runtime package management
- Flatpak Preinstall - GUI application setup
- ujust Commands - User convenience commands
- Build Scripts - Build-time customization
Test your changes before pushing:
just build # Build container image
just build-qcow2 # Build VM disk image
just run-vm-qcow2 # Test in browser-based VMThis template provides security features for production use:
- Optional SBOM generation (Software Bill of Materials) for supply chain transparency
- Optional image signing with cosign for cryptographic verification
- Automated security updates via Renovate
- Build provenance tracking
These security features are disabled by default to allow immediate testing. When you're ready for production, see the "Love Your Image? Let's Go to Production" section above to enable them.
Template maintained by Universal Blue Project