- Complete documentation for all bootc commands and subcommands - Debian-specific adaptations and workarounds - Manual installation methods to bypass bootc reliability issues - Technical guides with Rust source code analysis - Flowcharts and external command references - Hidden command documentation (bootc internals, state, etc.) - Composefs integration analysis - Base image creation guides (with and without bootc binary) - Management scripts and automation - Comprehensive troubleshooting and examples
11 KiB
bootc Technical Installation Guide
Overview
This document provides a comprehensive technical explanation of how bootc installs container images as bootable operating systems. bootc bridges the gap between OCI/Docker container images and bootable host systems by providing installation mechanisms that create traditional Linux boot environments from container images.
Architecture Overview
bootc operates in two distinct modes:
- Container Mode: When run inside a container (during build), behaves like any other container
- Host Mode: When installed to a physical/virtual machine, becomes the bootable OS
The installation process transforms a container image into a bootable system with:
- Bootloader configuration
- Kernel and initramfs setup
- Root filesystem deployment
- OSTree repository initialization
Installation Commands
Primary Installation Commands
bootc install to-disk- Direct installation to a block devicebootc install to-filesystem- Installation to an existing mounted filesystembootc install to-existing-root- Convert existing Linux system to bootcbootc install finalize- Post-installation finalization
Command Structure
bootc install [COMMAND] [OPTIONS] [TARGET]
Technical Installation Process
Phase 1: Preparation and Validation
1.1 Container Environment Detection
// From install.rs:519-538
pub(crate) fn from_container(
root: &Dir,
container_info: &ContainerExecutionInfo,
) -> Result<Self> {
if !container_info.engine.starts_with("podman") {
anyhow::bail!("Currently this command only supports being executed via podman");
}
// ... validation logic
}
External Commands Required:
podman- Container runtime (required)ostree- OSTree repository managementbootupd- Bootloader management
1.2 Privilege and Namespace Validation
// From install.rs:1061-1082
fn require_host_pidns() -> Result<()> {
if rustix::process::getpid().is_init() {
anyhow::bail!("This command must be run with the podman --pid=host flag")
}
Ok(())
}
Required Container Flags:
--privileged- Full host access--pid=host- Host process namespace--security-opt label=type:unconfined_t- SELinux bypass
1.3 SELinux State Management
// From install.rs:1001-1029
pub(crate) fn reexecute_self_for_selinux_if_needed(
srcdata: &SourceInfo,
override_disable_selinux: bool,
) -> Result<SELinuxFinalState> {
// SELinux policy detection and re-execution logic
}
Phase 2: Filesystem Setup
2.1 OSTree Repository Initialization
// From install.rs:591-694
async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result<(Storage, bool)> {
let has_ostree = rootfs_dir.try_exists("ostree/repo")?;
if !has_ostree {
Task::new("Initializing ostree layout", "ostree")
.args(["admin", "init-fs", "--modern", "."])
.cwd(rootfs_dir)?
.run()?;
}
// ... repository configuration
}
External Commands:
ostree admin init-fs --modern- Initialize OSTree filesystemostree config set- Configure repository settings
2.2 Container Image Deployment
// From install.rs:718-892
async fn install_container(
state: &State,
root_setup: &RootSetup,
sysroot: &ostree::Sysroot,
has_ostree: bool,
) -> Result<(ostree::Deployment, InstallAleph)> {
// Pull container image into OSTree repository
let pulled_image = match prepare_for_pull(repo, &spec_imgref, Some(&state.target_imgref)).await? {
PreparedPullResult::AlreadyPresent(existing) => existing,
PreparedPullResult::Ready(image_meta) => {
check_disk_space(root_setup.physical_root.as_fd(), &image_meta, &spec_imgref)?;
pull_from_prepared(&spec_imgref, false, ProgressWriter::default(), *image_meta).await?
}
};
// ... deployment logic
}
Phase 3: Bootloader Installation
3.1 Bootupd Integration
// From install.rs:1337-1343
crate::bootloader::install_via_bootupd(
&rootfs.device_info,
&rootfs.physical_root_path,
&state.config_opts,
&deployment_path.as_str(),
)?;
External Commands:
bootupctl install- Install bootloaderbootupctl generate- Generate bootloader configuration
3.2 Architecture-Specific Bootloaders
- x86_64/aarch64: GRUB2 via bootupd
- s390x: zipl (IBM Z)
- Other: Platform-specific implementations
Phase 4: Kernel and Initramfs Setup
4.1 Kernel Argument Processing
// From install.rs:773-825
let kargsd = crate::bootc_kargs::get_kargs_from_ostree_root(
&sysroot.repo(),
merged_ostree_root.downcast_ref().unwrap(),
std::env::consts::ARCH,
)?;
Kernel Arguments Sources (in order):
- Root filesystem kargs
- Install configuration kargs
- Container image kargs.d files
- CLI-specified kargs
4.2 Initramfs Integration
- Kernel location:
/usr/lib/modules/$kver/vmlinuz - Initramfs location:
/usr/lib/modules/$kver/initramfs.img - Generated by dracut during container build
Phase 5: Filesystem Finalization
5.1 Filesystem Optimization
// From install.rs:1033-1058
pub(crate) fn finalize_filesystem(
fsname: &str,
root: &Dir,
path: impl AsRef<Utf8Path>,
) -> Result<()> {
// fstrim - optimize filesystem
Task::new(format!("Trimming {fsname}"), "fstrim")
.args(["--quiet-unsupported", "-v", path.as_str()])
.cwd(root)?
.run()?;
// Remount read-only
Task::new(format!("Finalizing filesystem {fsname}"), "mount")
.cwd(root)?
.args(["-o", "remount,ro", path.as_str()])
.run()?;
// Freeze/thaw for journal flush
for a in ["-f", "-u"] {
Command::new("fsfreeze")
.cwd_dir(root.try_clone()?)
.args([a, path.as_str()])
.run_capture_stderr()?;
}
}
External Commands:
fstrim- Trim filesystem for optimizationmount -o remount,ro- Remount read-onlyfsfreeze- Freeze/thaw for journal flush
Installation Modes
1. to-disk Installation
Process Flow:
- Create filesystem on target device
- Mount target device
- Deploy container image to mounted filesystem
- Install bootloader
- Unmount and finalize
External Commands:
mkfs.$filesystem_type /dev/target
mount /dev/target /mnt
bootc install to-filesystem --karg=root=UUID=<uuid> /mnt
umount /mnt
2. to-filesystem Installation
Process Flow:
- Validate target filesystem
- Initialize OSTree repository
- Deploy container image
- Configure bootloader
- Finalize filesystem
Use Cases:
- Integration with external installers (Anaconda)
- Custom partitioning schemes
- Cloud image generation
3. to-existing-root Installation
Process Flow:
- Mount host root filesystem
- Clean boot directories
- Deploy alongside existing system
- Configure bootloader
- Set up cleanup service
Special Considerations:
- Preserves existing data in
/sysroot - Requires
--acknowledge-destructiveflag - Sets up cleanup service for first boot
External Dependencies
Required System Commands
| Command | Purpose | Package |
|---|---|---|
ostree |
OSTree repository management | ostree |
bootupd |
Bootloader management | bootupd |
podman |
Container runtime | podman |
fstrim |
Filesystem optimization | util-linux |
mount |
Filesystem mounting | util-linux |
umount |
Filesystem unmounting | util-linux |
fsfreeze |
Filesystem freeze/thaw | util-linux |
Optional Commands
| Command | Purpose | Package |
|---|---|---|
cryptsetup |
LUKS encryption | cryptsetup |
grub2-mkconfig |
GRUB configuration | grub2-tools |
dracut |
Initramfs generation | dracut |
Configuration Files
1. Install Configuration
Location: /usr/lib/bootc/install/*.toml
[install.filesystem.root]
type = "xfs"
[install.filesystem.boot]
type = "ext4"
2. Kernel Arguments
Location: /usr/lib/bootc/kargs.d/*.toml
[kargs]
append = ["console=ttyS0", "quiet"]
prepend = ["rd.luks.uuid=12345678-1234-1234-1234-123456789abc"]
3. OSTree Configuration
Location: ostree/repo/config
[core]
repo_version=1
mode=bare
[sysroot]
bootloader=none
bootprefix=true
readonly=true
Security Considerations
1. SELinux Integration
- Automatic policy detection
- Re-execution for proper labeling
- Target system SELinux configuration
2. Container Security
- Requires privileged container execution
- Host mount namespace access
- Device access for installation
3. Filesystem Security
- Atomic operations where possible
- Proper file permissions
- SELinux labeling
Error Handling and Recovery
1. Disk Space Validation
// From install.rs:696-715
fn check_disk_space(
repo_fd: impl AsFd,
image_meta: &PreparedImportMeta,
imgref: &ImageReference,
) -> Result<()> {
let stat = rustix::fs::fstatvfs(repo_fd)?;
let bytes_avail: u64 = stat.f_bsize * stat.f_bavail;
if image_meta.bytes_to_fetch > bytes_avail {
anyhow::bail!(
"Insufficient free space for {image} (available: {bytes_avail} required: {bytes_to_fetch})",
// ... error details
);
}
}
2. Rollback Capability
- OSTree provides atomic rollback
- Bootloader configuration backup
- Deployment state tracking
3. Validation Steps
- Container image integrity
- Filesystem compatibility
- Bootloader support
- Kernel compatibility
Performance Considerations
1. Parallel Operations
- Container image pulling
- Filesystem operations
- Bootloader installation
2. Disk I/O Optimization
- OSTree repository configuration
- Filesystem trimming
- Write optimization
3. Memory Usage
- Container image caching
- OSTree repository management
- Temporary file handling
Debugging and Troubleshooting
1. Logging
- Structured logging with tracing
- Journal integration
- Progress reporting
2. Common Issues
- Insufficient disk space
- SELinux policy conflicts
- Bootloader installation failures
- Container image access issues
3. Debug Commands
# Check OSTree repository
ostree admin status
# Verify bootloader
bootupctl status
# Check container image
podman images
# Validate filesystem
lsblk -f
Future Enhancements
1. Planned Features
- Dynamic ConfigMap injection
- Enhanced rollback mechanisms
- Multi-architecture support
- Cloud integration improvements
2. API Evolution
- Stable CLI interface
- REST API for management
- Configuration management
- Monitoring integration
This technical guide provides the foundation for understanding bootc's installation process. The system is designed to be robust, secure, and maintainable while providing the flexibility needed for various deployment scenarios.