Immutablue Build Customization#
This guide provides detailed information on customizing the Immutablue build process to create your own variants of the system.
Understanding The Build Process#
Immutablue uses a multistage build process to create OCI-compliant container images. The build is structured in a way that makes it easy to customize and extend.
Build Stages#
The Immutablue build process consists of the following stages, each represented by a script in the build/ directory:
- 00-pre: Early build preparation
- 10-copy: Copy files from mounted containers
- 20-add-repos: Add package repositories
- 30-install-packages: Install RPM packages
- 40-uninstall-packages: Remove unwanted packages
- 50-remove-files: Remove unwanted files
- 60-services: Configure systemd services
- 90-post: Final post-build tasks
Additionally, there’s a 99-common.sh script that provides common functions used by the other scripts.
Build Options#
Immutablue supports various build options that can be combined to create custom builds:
Desktop Environment Options#
Each of these options selects a different desktop environment:
- silverblue: GNOME desktop (default)
- kinoite: KDE Plasma desktop
- sericea: Sway window manager
- onyx: Budgie desktop
- vauxite: XFCE desktop
- lazurite: LXQt desktop
- cosmic: COSMIC desktop
- nucleus: No desktop environment (headless)
Feature Options#
These options add specific features to the build:
- asahi: Support for Apple Silicon hardware
- cyan: Support for NVIDIA graphics
- lts: Use LTS kernel (automatically includes ZFS)
- zfs: Include ZFS filesystem support
- bazzite: Optimized for Steam Deck
- build_a_blue_workshop: Special build for n8n automation
Customizing Your Build#
To customize your Immutablue build, you can use the following approaches:
Command Line Options#
The make build command accepts various options to customize the build:
# Build with NVIDIA support
make CYAN=1 build
# Build with LTS kernel
make LTS=1 build
# Build a KDE Plasma version with NVIDIA support
make KINOITE=1 CYAN=1 build
# Build a headless version
make NUCLEUS=1 buildYou can combine multiple options to create a build that meets your specific needs.
Modifying packages.yaml#
The packages.yaml file is the central configuration file that controls what packages are installed, what repositories are added, and what services are enabled/disabled in the build.
Key sections include:
- repo_urls: Package repositories to add
- rpm: RPM packages to install
- rpm_url: URLs to RPM packages to download
- rpm_rm: RPM packages to remove
- file_rm: Files to remove
- services_enable_sys: System services to enable
- services_disable_sys: System services to disable
- services_mask_sys: System services to mask
- services_unmask_sys: System services to unmask
- flatpaks: Flatpaks to install
- flatpaks_rm: Flatpaks to remove
Each section supports version-specific, architecture-specific, and flavor-specific variants using nested keys:
- all: Applies to all versions, architectures, and flavors
- : Specific to a Fedora version (e.g.,
42,43) - all_x86_64: Only for x86_64 architecture
- all_aarch64: Only for aarch64 architecture
- gui: Only for GUI builds (under the appropriate section)
- silverblue: Only for GNOME builds
- kinoite: Only for KDE builds
- And combinations like
42_x86_64for version + architecture specific
File Overrides#
File overrides allow you to add or replace files in the final image. Place your files in the artifacts/overrides/ directory, maintaining the same directory structure as the root filesystem.
For example:
artifacts/overrides/etc/profile.d/my-profile.shwill be placed at/etc/profile.d/my-profile.shartifacts/overrides/usr/bin/my-scriptwill be placed at/usr/bin/my-script
This is particularly useful for adding custom scripts, configuration files, or replacing existing files with customized versions.
You can also use specialized override directories for specific variants:
artifacts/overrides_asahi/: Files specific to Asahi buildsartifacts/overrides_cyan/: Files specific to NVIDIA builds
Creating A Custom Image#
To create your own custom Immutablue image:
- Fork the
immutablue-customrepository (recommended over forking the main repository) - Modify the
packages.yamlfile to add/remove packages as needed - Add any custom files to
artifacts/overrides/ - Update the
settings.yamlfile with your custom settings - Build the image using
make buildwith your desired options
Example: Creating a Developer Workstation#
Here’s an example of creating a custom image optimized for software development:
Start with a base Immutablue image with NVIDIA support:
make CYAN=1 buildAdd development packages to
packages.yaml:immutablue: rpm: all: - cmake - gcc-c++ - git - golang - java-latest-openjdk-devel - nodejs - python3-devel - rust - code 43: # Additional packages for Fedora 43 - new-dev-tool-for-f43Add custom VS Code settings through file overrides:
artifacts/overrides/etc/skel/.config/Code/User/settings.jsonBuild and test your custom image.
Advanced Build Customization#
Custom Build Scripts#
For advanced customization, you can modify or add to the build scripts in the build/ directory. This allows you to customize the build process itself, rather than just the packages and files.
For example, to add a custom post-build step:
- Create a
custom-post.shscript in your fork - Add it to the build sequence in
Containerfile
Using Custom Repositories#
To add custom repositories:
Add the repository URL to
packages.yaml:immutablue: repo_urls: all: - name: my-custom-repo.repo url: https://example.com/my-custom-repo.repo 43: # Fedora 43 specific repository - name: f43-specific-repo.repo url: https://example.com/f43-repo.repoThe build process will download and install this repository file.
Building For Different Architectures#
Immutablue supports both x86_64 and aarch64 architectures. Use the PLATFORM variable to specify the target architecture:
make PLATFORM=linux/aarch64 buildNote that some features (like homebrew) are only available on specific architectures, and the build process will adjust accordingly.