This page describes how to create a minimal bootable amd64 Debian system (on a separate partition or an external drive or a qcow2 image) from a command line of another working Debian installation.
This page assumes some level of familiarity with the basic structure of a Linux system and its common config files.
ToDo: verify if just replacing amd64 for arm64 produces valid instructions for ARM CPUs.
Contents
Partition the target drive
For a storage device (like an HDD or an NVMe or a qcow2 image) to be a valid boot device for UEFI systems, it needs to have an EFI System Partition (ESP) containing EFI applications. If you are bootstrapping the system on a separate partition of a drive that already has some OS installed on itself, an ESP is most probably already there and you can skip to the next paragraph. Typically, EFI apps on an ESP are just early-stage bootloaders for installed OSes, like shim + 1st stage of Grub in case of Linux, which are just a few to few dozens of MB in size, so 200MB will be perfectly sufficient in most cases. Per UEFI spec, ESP must be formatted as FAT and FAT32 is the safest choice in practice. It is a common practice for an ESP to be the first physical partition on a given disk, but this is not mandatory.
A standard Debian system requires at least one partition or a logical volume for its root filesystem (rootFS). Optionally, separate subvolumes (partitions or logical volumes) may exist for /var, /home, /boot, /opt etc. rootFS may be formatted as any Linux-supported, POSIX-compliant filesystem (ext4, xfs, btrfs etc). As of Trixie, a text-only Debian system will easily fit within 3GB, for a graphical system at least 10GB is recommended.
There are several different strategies and additional technologies (for example LVM, partitions for swap space, LUKS etc) for partition layouts, each with different strengths and goals, but this is beyond the scope of this document: refer to the links in the following subsection.
Related tools and guides
fdisk disk partitioning tool
parted another disk partitioning tool
General info on partitioning
qemu-img tool for creating disk images (qcow2 or raw) for QEMU VMs
qemu-nbd tool for connecting qcow2 disk images to a system's device nodes
A mini-HowTo on mounting qcow2 images
Mount volumes and run mmdebstrap
Create a temporary mount-point for the target system, for example /mnt/tmp-debstrap, it will be referred hereafter to as ${debstrapFolder}. Mount the rootFS volume there, then mount any subvolumes at their respective mount-points. Afterwards run mmdebstrap:
sudo mmdebstrap --architectures=amd64 --skip=output/dev,output/mknod,check/empty --variant=standard trixie "${debstrapFolder}" /etc/apt/sources.listThis will create a basic amd64 foundation of the new system using apt sources copied from host's /etc/apt/sources.list.
Replace /etc/apt/sources.list, if you want to use different sources. This is mandatory if you want to bootstrap a different release than the one of your host.
Replace trixie with the desired Debian version (the passed version must match the passed sources).
In certain scenarios, you probably can getaway with just important or even minbase as --variant instead of standard.
If you intend to run i386 binaries on the target system, you can right away pass amd64,i386 in --architectures.
If you often use mmdebstrap, consider setting up AptCacherNg on the host system and adding --aptopt='Acquire::http { Proxy "http://127.0.0.1:3142"; }' option to mmdebstrap. In case of a separate bootable system, you then need to remove the proxy setting from "${debstrapFolder}/etc/apt/apt.conf.d/99mmdebstrap" (or the whole file if there's nothing else there).
Create or edit basic config files
/etc/fstab
mmdebstrap creates just an empty stub, so you need to list the rootFS and any subvolumes manually, including the ESP at /boot/efi.
/etc/hostname
Put a hostname of your choice into this file, for example:
echo my-new-laptop |sudo tee "${debstrapFolder}/etc/hostname"
/etc/hosts
mmdebstrap creates entries necessary for basic networking, so just add an entry for the hostname chosen above:
echo "127.0.1.1 $(cat ${debstrapFolder}/etc/hostname)" | sudo tee -a "${debstrapFolder}/etc/hosts"If you want to set a static DNS domainame, then instead add an entry that also includes an alias for the desired FQDN, for example:
echo "127.0.1.1 $(cat ${debstrapFolder}/etc/hostname).my-dns-domain $(cat ${debstrapFolder}/etc/hostname)" | sudo tee -a "${debstrapFolder}/etc/hosts"See hostname for details.
/etc/localtime
mmdebstrap by default sets the timezone to UTC, change the link to point to your desired timezone, for example:
sudo ln -sf /usr/share/zoneinfo/Europe/Warsaw "${debstrapFolder}/etc/localtime"
chroot to the target system
Consider exporting temporarily LANG=C.UTF-8, then follow the basic procedure as described on chroot wiki and mount /boot/efi, if you haven't done so yet (note: if the target system shares ESP with the host system, you must either umount on the host first or use --bind option for mount).
Configure locales
If you don't want to change LANG to C.UTF-8, it's useful to perform this step early, to prevent the next steps from complaining. You can perform this step in 1 of 2 ways:
Interactively: run
dpkg-reconfigure locales
...and it will ask which locales to enable and which of these should be the default.- Non-Interactively:
Put your desired locales into /etc/locale.gen file, 1 per line, for example:
en_IE.UTF-8 UTF-8 vi_VN UTF-8
See /usr/share/i18n/SUPPORTED file for the full list of supported options.
Run
locale-gen
If you want to set a system-wide default locales, use update-locale program to set values for Lang and LANGUAGE vars in /etc/locale.conf file, for example:
update-locale LANG=en_IE.UTF-8 LANGUAGE="en_IE:en"
Make sure that /etc/default/locale link points to ../locale.conf file, if it doesn't, run
ln -sf ../locale.conf /etc/default/locale
See Locale page for more info.
Install Grub, initramfs-tools, keyboard-configuration and fontconfig-config
These packages are necessary for the packages from the next step (kernel & firmware) to be integrated into the boot process:
apt update apt install grub-efi initramfs-tools keyboard-configuration fontconfig-config
Next run grub-install command: if this is the only Debian installation on this physical drive, no arguments are needed and an EFI app named debian will be added to the ESP. Otherwise you need to provide an alternative name using --bootloader-id, for example:
grub-install --bootloader-id=my-test-trixie
Install a kernel, necessary firmware and other critical packages
Use apt install to install the below packages:
Kernel: linux-image-amd64
- Necessary firmware: this depends on the specific hardware of the target system and typically includes:
At least one of firmware-{amd,intel,nvidia}-graphics for the GPU.
If the target system uses a WiFi, then its firmware, usually one of firmware-iwlwifi, firmware-mediatek, firmware-brcm80211, firmware-atheros, firmware-ath9k-htc.
If the target system uses a wired ethernet, then its firmware (ToDo: list typical wired eth firmware).
If the target system has any critical devices (like its only keyboard or its only display) connected via a Thunderbolt, then bolt is necessary and at least initially, Thunderbolt security needs to be disabled in UEFI settings.
It is a common practice to not set a password for root user, in which case sudo is necessary.
After installing all the above packages, run
update-grub
Create user accounts and set passwords
If password for root user was not set, it is necessary to create at least 1 user account, for example:
adduser myusername
This will interactively ask for user details and password (replace myusername with a username of your choice, of course).
This account must be able to use sudo, so it must be added to sudo group:
adduser myusername sudo
If you want to change a password for any user (or set it, for example for root user), run
passwd myusername
Install common tools and utils (optional)
You may find some of the below useful:
curl: universal network fetching tool
network-manager: network configuration tool
firewall of your choice, for example ufw, firewalld etc
fwupd: firmware updater
unattended-upgrades: installs security upgrades automatically
gpm: allows copy-pasting with a mouse on text consoles
bluetooth: allows to pair Bluetooth devices
console-based text editor of your choice: by default only nano and vim.tiny are installed
Install a graphic system (optional)
Install a desktop environment of your choice
MATE: apt install mate-desktop-environment-extras lightdm package-update-indicator
Gnome: apt install gnome-session gnome-software
ToDo: add other common DEs
Common GUI apps
firefox-esr: web browser
gufw: configurator for ufw firewall
synaptic: package manager
network-manager-gnome: configurator for network-manager for Gnome and MATE
Exit chroot and cleanup
Exit the chroot either with exit command or by pressing CTRL+D, then umount all the volumes and bind-mounts of the target system:
sudo umount -R "${debstrapFolder}"You should now be able to boot the target machine using the created system.
