mkarchiso requires absolute paths. Clean work dir explicitly and pass PWD-based paths to -w, -o, and the profile directory.
Complete Guide to Creating a Custom Arch Linux ISO
DistroTube: https://www.youtube.com/watch?v=tSGGBbJBgvk&t=1228s
Dotfiles install file structure:
AlvinArch/
├── airootfs/
│ ├── etc/skel/
│ │ ├── .config/bat/ # bat + catppuccin theme
│ │ ├── .config/fish/ # 20 files, quickshell guard
│ │ ├── .config/nvim/ # LazyVim (14 files)
│ │ ├── .config/hypr/custom/ # 8 files (kdeconnectd + cursor only)
│ │ ├── .config/starship.toml
│ │ ├── .zshrc # adapted (no hardcoded paths)
│ │ └── .fzf.zsh
│ └── root/customize_airootfs.sh # pre-installs oh-my-zsh, lazy.nvim, plugins
├── localrepo/
│ ├── build-end4-deps.sh # non-interactive AUR build (all deps)
│ ├── end4-pkgbuilds/ # microtex-git, quickshell-git, bibata
│ ├── illogical-impulse-quickshell-git-*.pkg.tar.zst
│ ├── illogical-impulse-bibata-modern-classic-bin-*.pkg.tar.zst
│ └── update.sh # existing, regenerates repo db
└── packages.x86_64 # 420 packages (65+ end-4 deps added)
Table of Contents
- Overview
- Prerequisites
- Directory Structure
- Core Configuration Files
- User Configuration (skel/)
- System Services & Networking
- Local Repository (localrepo/)
- Boot Configuration
- Build & Test
- Planned Additions
- Troubleshooting
Overview
AlvinArch is a custom Arch Linux live ISO built on the archiso framework. It ships a Hyprland desktop with end-4 dots-hyprland, a curated set of ~400 packages, and a local repository of pre-built AUR packages for packages not available in official repos. The ISO targets both real hardware and VMs (VirtualBox/Hyper-V/VMware guest services are enabled out of the box).
Key Features
- Hyprland + end-4 — Wayland compositor with illogical-impulse dotfiles (quickshell, bibata cursors, microtex)
- LazyVim — Pre-configured Neovim with lazy.nvim and curated plugins
- Fish + Zsh + Starship — Dual shell setup with oh-my-zsh and a cross-shell prompt
- Local AUR repo — Pre-built packages (end-4 deps, wallust, grub-customizer, etc.) that aren't in official repos
- Curated packages — ~400 packages across ccache, networking, dev tools, and desktop utilities
- Guest VM support — VirtualBox, Hyper-V, and VMware tools auto-enabled
Prerequisites
Required Tools
# Install archiso and dependencies
sudo pacman -S archiso git base-devel
# Optional but recommended
sudo pacman -S arch-install-scripts squashfs-tools
Knowledge Requirements
- Basic Linux system administration
- Understanding of Arch Linux package management
- Shell scripting basics
- Git version control (for managing your project)
Directory Structure
Complete Project Layout
AlvinArch/
├── profiledef.sh # ISO metadata, compression, boot modes, file permissions
├── packages.x86_64 # ~400 live-environment packages (Hyprland, end-4, dev tools)
├── bootstrap_packages # Minimal build-time packages (base, arch-install-scripts)
├── pacman.conf # Repos: cachyos → core → extra → multilib → chaotic-aur → local-aur
├── airootfs/ # Root filesystem overlay (copied into live ISO)
│ ├── etc/
│ │ ├── os-release # NAME="Alvin Arch Linux", ID=arch
│ │ ├── hostname # Default hostname: archiso
│ │ ├── motd # Welcome text with install instructions and color bar
│ │ ├── locale.conf # LANG=en_AU.UTF-8
│ │ ├── locale.gen # Locale generation file
│ │ ├── localtime → ../usr/share/zoneinfo/... # Timezone symlink
│ │ ├── resolv.conf # DNS resolver config
│ │ ├── passwd # System user accounts
│ │ ├── shadow # Password hashes (mode 400)
│ │ ├── clamav/ # ClamAV antivirus config (certs, clamd, freshclam, milter)
│ │ ├── skel/ # Home directory template for new users
│ │ │ ├── .config/
│ │ │ │ ├── bat/ # bat + Catppuccin Macchiato theme
│ │ │ │ ├── fish/ # Fish shell config (~20 files, nvm, fisher, hyprland helper)
│ │ │ │ ├── nvim/ # LazyVim setup (init.lua, plugins/, config/)
│ │ │ │ ├── hypr/custom/ # Hyprland dotfiles (keybinds, rules, execs, env, general, scripts)
│ │ │ │ └── starship.toml # Starship cross-shell prompt
│ │ │ ├── .zshrc # Zsh config (oh-my-zsh compatible)
│ │ │ └── .fzf.zsh # Fzf shell integration
│ │ ├── systemd/
│ │ │ ├── system/ # Service files and enablement symlinks
│ │ │ │ ├── choose-mirror.service # Auto mirror selection
│ │ │ │ ├── pacman-init.service # Keyring initialization
│ │ │ │ ├── livecd-alsa-unmuter.service # Unmute ALSA on boot
│ │ │ │ ├── livecd-talk.service # LiveCD talk helper
│ │ │ │ ├── multi-user.target.wants/ # Enabled services (iwd, NetworkManager, sshd, vboxservice,
│ │ │ │ │ # hv_kvp/vss/fcopy, vmtoolsd, ModemManager, etc.)
│ │ │ │ ├── sysinit.target.wants/ # systemd-timesyncd, systemd-time-wait-sync
│ │ │ │ ├── sockets.target.wants/ # systemd-networkd, pcscd
│ │ │ │ ├── network-online.target.wants/ # systemd-networkd-wait-online
│ │ │ │ └── sound.target.wants/ # livecd-alsa-unmuter
│ │ │ ├── networkd.conf.d/ # IPv6 privacy extensions
│ │ │ ├── resolved.conf.d/ # systemd-resolved config
│ │ │ ├── journald.conf.d/ # Volatile journal storage
│ │ │ └── logind.conf.d/ # Do-not-suspend policy
│ │ ├── pacman.d/
│ │ │ ├── hooks/
│ │ │ │ ├── uncomment-mirrors.hook # Enable mirrors after install
│ │ │ │ └── zzzz99-remove-custom-hooks-from-airootfs.hook
│ │ │ ├── chaotic-mirrorlist # Chaotic AUR mirrors
│ │ │ └── cachyos-mirrorlist # CachyOS mirrors
│ │ ├── ssh/sshd_config.d/ # SSH live-environment config (10-archiso.conf)
│ │ ├── modprobe.d/ # broadcom-wl.conf (Broadcom WiFi driver)
│ │ └── mkinitcpio.conf.d/ # archiso initramfs config
│ ├── usr/
│ │ ├── lib/os-release # usr-merge os-release
│ │ ├── local/bin/ # choose-mirror, Installation_guide, livecd-sound
│ │ ├── local/share/livecd-sound/ # ALSA config (asound.conf.in)
│ │ └── share/pacman/keyrings/ # CachyOS GPG keyring + trust data
│ └── root/
│ ├── .automated_script.sh # Automated install entry point
│ ├── .zlogin # Zsh login hook
│ ├── .gnupg/scdaemon.conf # GPG smartcard config
│ ├── .live-pacman.conf # Pacman config for live session
│ └── customize_airootfs.sh # Build-time chroot script (oh-my-zsh, lazy.nvim, plugins)
├── localrepo/ # Pre-built AUR packages (indexed as local-aur repo)
│ ├── build-end4-deps.sh # Non-interactive AUR builder for end-4 dependencies
│ ├── update.sh # Regenerates repo DB + syncs names to packages.x86_64
│ ├── end4-pkgbuilds/ # PKGBUILDs: quickshell-git, microtex-git, bibata-modern-classic-bin
│ ├── *.pkg.tar.zst # Pre-built packages (illogical-impulse-*, wallust, grub-customizer,
│ │ # snapd, upscayl, meshy-git, pacserve, etc.)
│ └── local-aur.db{,.tar.gz} # Repo database files
├── efiboot/ # UEFI boot (systemd-boot)
│ └── loader/
│ ├── loader.conf
│ └── entries/
│ ├── 01-archiso-linux.conf
│ ├── 02-archiso-speech-linux.conf
│ └── 03-archiso-memtest86+x64.conf
├── grub/ # GRUB boot (BIOS + UEFI)
│ ├── grub.cfg
│ └── loopback.cfg
└── syslinux/ # BIOS boot (syslinux)
├── syslinux.cfg
├── archiso_head.cfg
├── archiso_pxe-linux.cfg
├── archiso_sys.cfg
├── archiso_sys-linux.cfg
├── archiso_tail.cfg
└── splash.png
Core Configuration Files
profiledef.sh
Defines the entire ISO build. Key settings: iso_label="AlvinArch_...", bootmodes (BIOS syslinux + UEFI systemd-boot), airootfs_image_type="squashfs" with xz compression. Edit first to change branding or compression.
packages.x86_64
The main package list (~400 packages). Packages from allowed repos (cachyos, extra, multilib, chaotic-aur) are installed directly. Packages in localrepo/*.pkg.tar.zst are pulled from the [local-aur] repo. Keep sorted alphabetically.
bootstrap_packages
Minimal packages for the mkarchiso bootstrap phase: base and arch-install-scripts.
pacman.conf
Defines the repo order: cachyos → core → extra → multilib → chaotic-aur → local-aur. The [local-aur] repo points to the local localrepo/ directory for pre-built AUR packages.
User Configuration (skel/)
Dotfiles in airootfs/etc/skel/ are copied into every new user's home directory on the live ISO.
.config/bat/
bat with a Catppuccin Macchiato color theme. Provides bat as a cat replacement.
.config/fish/
Fish shell configuration (~20 files). Includes nvm integration, fisher plugin manager, Hyprland auto-detection (auto-Hypr.fish), frozen theme/keybindings, and custom functions (edit, update, lzd).
.config/nvim/
Full LazyVim setup powered by lazy.nvim. Includes init.lua, plugin specs for Obsidian, Arduino, and Harper (grammar), plus standard LazyVim config/options/keymaps/autocmds.
.config/hypr/custom/
Hyprland dotfiles from end-4 dots-hyprland:
| File | Purpose |
|---|---|
keybinds.lua |
Window manager keybindings |
general.lua |
Appearance, gaps, border settings |
rules.lua |
Window rules (floating, size, class matching) |
execs.lua |
Autostart commands |
env.lua |
Environment variables |
variables.lua |
Shared variable definitions |
scripts/ |
Helper scripts (video wallpaper restore, paste-as-type) |
.config/starship.toml
Cross-shell prompt config for Starship. Works with both Fish and Zsh.
.zshrc / .fzf.zsh
Zsh configuration adapted for oh-my-zsh (installed by customize_airootfs.sh) and fzf shell integration.
System Services & Networking
Services (enabled via symlinks)
| Service | Purpose |
|---|---|
iwd |
WiFi management |
NetworkManager |
Network connections |
sshd |
SSH access to live environment |
vboxservice |
VirtualBox guest additions |
hv_kvp_daemon, hv_vss_daemon, hv_fcopy_daemon |
Hyper-V integration |
vmtoolsd, vmware-vmblock-fuse |
VMware guest tools |
ModemManager |
Mobile broadband |
pacman-init |
Initializes GPG keyring before package operations |
choose-mirror |
Auto mirror selection (triggered by mirror kernel param) |
livecd-alsa-unmuter |
Unmutes audio on live boot |
Network Config
- systemd-networkd with IPv6 privacy extensions enabled
- systemd-resolved for DNS
- DHCP auto-configured for wired (ethernet) and wireless (iwd)
Other System Config
- ClamAV — Antivirus daemon config included in
airootfs/etc/clamav/ - mkinitcpio — Archiso-specific initramfs config
- logind — No-suspend policy for live session
- journald — Volatile (in-memory) log storage
Local Repository (localrepo/)
Pre-built AUR packages that aren't available in any allowed repo. The local-aur repo is configured in pacman.conf and picked up automatically by mkarchiso.
Scripts
build-end4-deps.sh— Non-interactive AUR build for all end-4 (illogical-impulse) dependencies. Run--quickto skip large packages.update.sh— Regenerates the repo database and syncs new package names topackages.x86_64.
end4-pkgbuilds/
Custom PKGBUILDs for end-4 metapackages:
quickshell-git— Quickshell (Qt6/QML shell for Wayland)microtex-git— LaTeX previewerbibata-modern-classic-bin— Bibata cursor theme
Pre-built Packages
Packages like illogical-impulse-quickshell-git, illogical-impulse-bibata-modern-classic-bin, wallust, grub-customizer, snapd, upscayl-bin, meshy-git, xwaylandvideobridge, pacserve, etc.
Boot Configuration
UEFI — systemd-boot (efiboot/)
Three boot entries: standard Arch Linux, speech/accessibility, and MemTest86+.
BIOS — GRUB (grub/)
grub.cfg for BIOS/CSM boot, loopback.cfg for booting the ISO from a mounted image.
BIOS — syslinux (syslinux/)
Legacy BIOS boot with custom splash screen. Includes PXE network boot config.
Build & Test
Building the ISO
# Build the ISO (repo root IS the profile directory)
sudo mkarchiso -v -w work -o out/ .
# Build AUR deps for end-4 (run locally before ISO build if localrepo/ is stale)
./localrepo/build-end4-deps.sh # build all
./localrepo/build-end4-deps.sh --quick # skip large AUR pkgs
# Refresh localrepo DB after adding/moving .pkg.tar.zst files
./localrepo/update.sh # re-indexes existing packages
./localrepo/update.sh pkg1.pkg.tar.zst # add files, then re-index
CI Checks (must pass before merge)
- ShellCheck: all
.shfiles checked withshellcheck -x -s bash - yamllint: all
.yml/.yamlfiles (relaxed config) - packages.x86_64 syntax: one package per line, no trailing whitespace,
[a-zA-Z0-9._@+\-]+only - Package repo check: every package in
packages.x86_64must be resolvable viapacman -Siin allowed repos (cachyos,extra,multilib,chaotic-aur), OR have a pre-built.pkg.tar.zstinlocalrepo/, OR appear inlocalrepo/build-end4-deps.sh
Recommended VirtualBox Settings (for testing)
- RAM: 4GB minimum, 8GB recommended
- Video Memory: 128MB
- 3D Acceleration: Enabled
- Storage: 40GB minimum
Guest additions (vboxservice), Hyper-V (hv_*), and VMware (vmtoolsd) tools are all auto-enabled in the live environment.
Planned Additions
The following dotfiles are not yet included but are planned for future versions:
| Component | Status | Notes |
|---|---|---|
| Alacritty terminal config | 🚧 Planned | Catppuccin Macchiato theme to match bat |
| GTK 3.0/4.0 theme config | 🚧 Planned | Consistent theming across GTK apps |
| Fontconfig custom settings | 🚧 Planned | Font rendering and fallback rules |
| Dunst notification daemon | 🚧 Planned | Notification appearance and behavior |
Troubleshooting
ISO won't boot
- Verify the ISO was built with
sudo mkarchiso(not as a regular user) - Check that UEFI or BIOS/CSM is correctly set in VM firmware settings
- For Ventoy: use the
.isodirectly, don't extract
No network in live environment
iwdhandles WiFi — runiwctlto connect manually if NetworkManager doesn't detect networks- Ethernet via systemd-networkd with DHCP should work automatically
Package installation fails during build
- Run
./localrepo/update.shto refresh the localrepo database - Ensure
localrepo/*.pkg.tar.zstfiles are valid and not corrupted - Check that the package name in
packages.x86_64matches exactly
LazyVim / oh-my-zsh not installed
customize_airootfs.shclones repos at build time — requires network access duringmkarchiso- Check build logs for git clone failures
Acknowledgements
- Arch Linux and the archiso project
- end-4 dots-hyprland for the illogical-impulse Hyprland config
- LazyVim for the Neovim starter config
- DistroTube for the archiso walkthrough that inspired this project