Create Custom Image with Debian Live Build lufy May 21, 2026 # Prepare rootfs 1. Install necessary packages ``` apt install -y grub-pc-bin \ grub-efi-amd64-bin \ grub-common \ efibootmgr ``` 2. Clean unnecessary files ``` apt clean journalctl --vacuum-time=1s rm -rf /tmp/* truncate -s 0 /etc/machine-id rm -f /var/lib/dbus/machine-id rm -f /etc/ssh/ssh_host_* rm -f ~/.bash_history ``` 3. Create service for ssh key generating in the first boot ``` cat > /etc/systemd/system/regenerate-ssh-hostkeys.service << EOF [Unit] Description=Regenerate SSH host keys After=network.target [Service] Type=oneshot ExecStart=/usr/bin/ssh-keygen -A ExecStartPost=/bin/systemctl disable regenerate-ssh-hostkeys.service ExecStartPost=/bin/rm -f /etc/systemd/system/regenerate-ssh-hostkeys.service [Install] WantedBy=multi-user.target EOF systemctl enable regenerate-ssh-hostkeys.service ``` 4. Access source dist in another OS for vm, we could make this on host: ``` modprobe nbd max_part=16 qemu-nbd --connect=/dev/nbd0 /var/lib/vz/images/100/vm-100-disk-0.qcow2 # to find partitions on vm disk fdisk -l /dev/nbd0 mkdir /mnt/vmroot mount /dev/nbd0p2 /mnt/vmroot # if EFI exists mount /dev/nbd0p1 /mnt/vmroot/boot/efi ``` for hardware machine, we could boot from live OS, and mount the disk ``` lsblk mount /dev/sda2 /mnt/vmroot # if EFI exists mount /dev/sda1 /mnt/vmroot/boot/efi ``` 5. Make rootfs ``` cd /mnt/vmroot/ ## tested command -- with can-dev.ko.xz in tarball tar \ --xattrs \ --acls \ --numeric-owner \ --one-file-system \ --exclude=/proc \ --exclude=/sys \ --exclude=/dev \ --exclude=/run \ --exclude=/tmp \ --exclude=/mnt \ --exclude=/media \ -I 'zstd -19' \ -cpf /root/rootfs.tar.zst \ -C /mnt/vmroot . ## Check if file exists in tarball, basically, I've checked can-dev.ko.xz and x86_64-efi, for I've missed these files at first. tar -I zstd -tf rootfs.tar.zst | grep "file-name" ``` 5. cleanup mount ``` umount /root/vmroot/ # if the source OS is vm, we need disconnect nbd connection qemu-nbd --disconnect /dev/nbd0 # else if on hardware machine, we need copy rootfs.tar.zst, then reboot the system ``` # Edit rootfs.tar.zst (optional) If needed, we could change files in rootfs.tar.zst ## Use custom apt mirror url ``` cat > config/archives/mirror.list.chroot << EOF deb https://deb.debian.org/debian trixie main contrib non-free-firmware deb https://deb.debian.org/debian-security trixie-security main contrib non-free-firmware deb https://deb.debian.org/debian trixie-updates main contrib non-free-firmware EOF ``` # Build ISO file 1. Install live-build ``` apt update apt install \ live-build \ debootstrap \ squashfs-tools \ xorriso \ grub-pc-bin \ grub-efi-amd64-bin \ mtools \ dosfstools ``` 2. Build config ``` mkdir linxuos-build cd linxuos-build # create config lb config \ --distribution trixie \ --architectures amd64 \ --binary-images iso-hybrid \ --debian-installer none \ --bootappend-live "boot=live components quiet splash" \ --archive-areas "main contrib non-free-firmware" \ --mirror-bootstrap http://mirror.lzu.edu.cn/debian/ \ --mirror-chroot http://mirror.lzu.edu.cn/debian/ \ --mirror-binary http://mirror.lzu.edu.cn/debian/ \ --mirror-chroot-security http://mirrors.lzu.edu.cn/debian-security/ \ --mirror-binary-security http://mirrors.lzu.edu.cn/debian-security/ # alternative mirrors in China: # http://mirrors.ustc.edu.cn/debian-security/ # http://mirrors.ustc.edu.cn/debian/ # mkdir -p config/package-lists mkdir -p config/includes.binary mkdir -p config/includes.chroot # cat > config/package-lists/installer.list.chroot << EOF live-boot systemd-sysv dialog parted e2fsprogs dosfstools zstd grub-pc-bin grub-efi-amd64-bin efibootmgr firmware-linux firmware-linux-free firmware-linux-nonfree firmware-realtek firmware-iwlwifi linux-image-amd64 EOF cp ../rootfs.tar.zst config/includes.binary/ # create install script cat > config/includes.chroot/usr/local/bin/install-system << EOF #!/usr/bin/bash set -e ROOTFS="/run/live/medium/rootfs.tar.zst" error() { dialog --msgbox "$1" 10 60 exit 1 } #DISKS=$(lsblk -dpno NAME,SIZE,MODEL | \ #grep -E '/dev/(sd|nvme|vd)') # #TARGET=$(echo "$DISKS" | \ #dialog --stdout \ #--menu "Select installation disk" \ #20 76 10 \ #$(awk '{print $1, $2" "$3}' <<< "$DISKS")) MENU_ITEMS=() while read -r DEV SIZE MODEL; do [ -z "$MODEL" ] && MODEL="disk" MENU_ITEMS+=("$DEV" "$SIZE $MODEL") done < <( lsblk -dpno NAME,SIZE,MODEL | \ grep -E '/dev/(sd|nvme|vd|mmcblk)' ) TARGET=$( dialog \ --stdout \ --menu "Select installation disk" \ 20 76 10 \ "${MENU_ITEMS[@]}" ) [ -z "$TARGET" ] && error "No target selected." dialog --yesno \ "Erase ALL DATA on:\n\n$TARGET" \ 10 60 clear if [[ "$TARGET" =~ nvme ]] || [[ "$TARGET" =~ mmcblk ]]; then P1="${TARGET}p1" P2="${TARGET}p2" P3="${TARGET}p3" else P1="${TARGET}1" P2="${TARGET}2" P3="${TARGET}3" fi swapoff -a || true umount -R "${TARGET}"* 2>/dev/null || true fuser -km "${TARGET}"* || true wipefs -af "$TARGET" partprobe "$TARGET" parted -s "$TARGET" mklabel gpt parted -s "$TARGET" \ mkpart BIOSBOOT 1MiB 3MiB parted -s "$TARGET" \ set 1 bios_grub on parted -s "$TARGET" \ mkpart EFI fat32 3MiB 512MiB parted -s "$TARGET" set 2 esp on parted -s "$TARGET" \ mkpart ROOT ext4 512MiB 100% udevadm settle mkfs.vfat -F32 "$P2" mkfs.ext4 -F "$P3" mount "$P3" /mnt mkdir -p /mnt/boot/efi mount "$P2" /mnt/boot/efi tar \ --xattrs \ --acls \ -I zstd \ -xpf "$ROOTFS" \ -C /mnt ROOT_UUID=$(blkid -s UUID -o value "$P3") EFI_UUID=$(blkid -s UUID -o value "$P2") cat > /mnt/etc/fstab <<EOF UUID=$ROOT_UUID / ext4 defaults 0 1 UUID=$EFI_UUID /boot/efi vfat umask=0077 0 1 EOF mkdir -p /mnt/{dev,proc,sys} mount --bind /dev /mnt/dev mount --bind /proc /mnt/proc mount --bind /sys /mnt/sys chroot /mnt systemd-machine-id-setup mkdir -p /mnt/tmp /mnt/var/tmp /mnt/var/log /mnt/var/cache /mnt/run chmod 1777 /mnt/var/tmp /mnt/tmp chroot /mnt update-initramfs -u if [ -d /sys/firmware/efi ]; then chroot /mnt grub-install \ --target=x86_64-efi \ --efi-directory=/boot/efi \ --bootloader-id=LinxuOS \ --removable else chroot /mnt grub-install "$TARGET" fi chroot /mnt update-grub umount -R /mnt dialog --msgbox \ "Installation complete." \ 10 50 reboot EOF mkdir -p /mnt/{dev,proc,sys} mount --bind /dev /mnt/dev mount --bind /proc /mnt/proc mount --bind /sys /mnt/sys chroot /mnt systemd-machine-id-setup mkdir -p /mnt/tmp /mnt/var/tmp /mnt/var/log /mnt/var/cache /mnt/run chmod 1777 /mnt/var/tmp /mnt/tmp chroot /mnt update-initramfs -u if [ -d /sys/firmware/efi ]; then chroot /mnt grub-install \ --target=x86_64-efi \ --efi-directory=/boot/efi \ --bootloader-id=LinxuOS 、 --removable else chroot /mnt grub-install "$TARGET" fi chroot /mnt update-grub umount -R /mnt dialog --msgbox \ "Installation complete." \ 10 50 reboot EOF chmod +x config/includes.chroot/usr/local/bin/install-system # add auto start service cat > config/includes.chroot/etc/systemd/system/installer.service << EOF [Unit] Description=LinxuOS Installer After=multi-user.target [Service] Type=idle ExecStart=/usr/local/bin/install-system StandardInput=tty TTYPath=/dev/tty1 TTYReset=yes TTYVHangup=yes [Install] WantedBy=multi-user.target EOF # enable service, here we need use relative path to create link mkdir -p config/includes.chroot/etc/systemd/system/multi-user.target.wants ln -s ../installer.service \ config/includes.chroot/etc/systemd/system/multi-user.target.wants/installer.service # build iso lb clean lb build ``` Finally, we would get a file named \`live-image-amd64.hybrid.iso\` in \`linxuos-build\`.
Comments (0)
Leave a Comment
No comments yet. Be the first to comment!