Debian: Debootstrap Install (aka Installing Debian “the Arch Way”)

June 2023: an updated version of this post is available here: https://ianlecorbeau.github.io/blog/debian-debootstrap-install.html

I’m not going to start by listing a number of reasons why you might want to do this. Chances are, if you found this guide it’s because you wanted to try it out, and have your reasons. If you don’t have any, then perhaps just the fun of it and the learning experience is more than valid enough.

I do want to point out that if you’re doing this expecting something even more minimal than a standard netinstall with notning selected at tasksel (which is already minimal enough), you may or may not be disappointed. We’ll be using the –variant=minbase option, which will omit some packages, but chances are you’ll end up installing some of them later. Regardless, it’s still worth doing, so let’s get to it right away.

## Pre installation notes

  • It’s not a bad idea to do this in a virtual machine or an old computer first.
  • No matter what you do, make damn sure you’re formatting the right drive.
  • You can do this from a pre-existing install, but my recommendation is to use a live iso. I use my custom Debian with dwm iso to do this, but any live iso will do.
  • Do yourself a favor, before starting either drop to a TTY (and login if you have to) with ctrl+alt+f2, or use tmux. Reason: some terminals might misbehave when chrooted in the bootstrapped environment due to some missing packages. Using tmux or a TTY is quicker and simpler than hunting down those missing packages which will inevitably get installed later when you’re finished with this process.

## Switching to the root account

It’s a lot more convenient to switch to the root account. That way, no need to constantly type sudo. Just type:

sudo su

## Get the dependencies

We don’t need much dependencies. Only debootstrap and the Arch install scripts for convenience.

apt update && apt install debootstrap arch-install-scripts -y

## Formatting and partitioning

Format your drive. I’m not going to go into detail on that one, because there’s a lot of different tools that does the job (fdisk, cfdisk, parted, etc) and which one is the best is merely a question of preference. I use cfdisk just because it’s what I’m used to. This guide, however, assumes you’re going to use separate boot (if installing on EFI systems), swap, root and home partitions.

For convenience, and for the rest of this guide, we will assume that if this is a EFI install, the boot partition is sdX1, swap is sdX2, root is sdX3 and home is sdX4. If installed on legacy/Bios systems, swap is sdX1, root sdX2 and home sdX3. Replace X with the proper drive letter. Note: in KVM/QEMU, it’ll be vdX, rather than sdX.

Once the disk is formatted, make the partitions and mount them.

  • On EFI systems:
mkfs.fat -F 32 /dev/sdX1
mkswap /dev/sdX2
swapon /dev/sdX2
mkfs.ext4 /dev/sdX3
mkfs.ext4 /dev/sdX4

mount /dev/sdX3 /mnt
mkdir /mnt/home
mount /dev/sdX4 /mnt/home
  • On legacy/bios systems:
mkswap /dev/sdX1
swapon /dev/sdX1
mkfs.ext4 /dev/sdX2
mkfs.ext4 /dev/sdX3

mount /dev/sdX2 /mnt
mkdir /mnt/home
mount /dev/sdX3 /mnt/home

## Debootstrap

With the disk partitioned and partitions mounted, we now run the debootstrap command. We will need a cli text editor in the chroot to modify some files, so we include one already. I use vim, but choose whatever whatever floats your boat.

/usr/sbin/debootstrap --variant=minbase --include=vim bullseye /mnt http://deb.debian.org/debian/

## Generate fstab file

We need to create the fstab file. This is where the Arch install scripts come in handy. We’ll be using UUIDs with the -U option, rather than disk labels.

genfstab -U /mnt >> /mnt/etc/fstab

## Before chrooting

Before we chroot we’ll just save ourselves some trouble and copy the apt sources.list and adjtime file from the current system to the chroot.

cp /etc/apt/sources.list /mnt/etc/apt/sources.list
cp /etc/adjtime /mnt/etc/adjtime

If you’re planning on using ifupdown as your networking tool, and you’re doing this from a system which uses it, copy the interfaces file to the chroot.

cp /etc/network/interfaces /mnt/etc/network/interfaces

## Chroot

Now is the time to chroot into the deboostrapped system

arch-chroot /mnt

## Apt sources list

Before we chrooted, we copied an apt sources.list file. Depending on what medium is used to do the install, it’s possible you may need to comment out the “deb cdrom” lines. Just open the /etc/apt/sources.list file in your text editor and if those lines are present, either put a # symbol at the beginning of those lines, or outright remove them.

When you’re positive that the apt sources.list file is correct, update and install the apt-utils package.

apt update && apt install apt-utils

## Installing the kernel and init

Note: if you plan on going systemd free, it’ll go a bit smoother if you install the init system before the kernel. Simply swap the order in which you perform the following steps.

We need a kernel and init system. This could be done later but I prefer getting it out of the way first.

  • Kernel: here the default amd64 kernel is used, but you can choose any kernel that Debian offers
apt install linux-image-amd64
  • Init system. You can choose between systemd, OpenRC or Sysvinit.

Note: Runit is another good choice, but I haven’t installed it on Bullseye so I don’t know how well it works there. Hence why it’s been left out. Though it should work relatively well.

Systemd:

apt install systemd systemd-sysv libpam-systemd libsystemd0

OpenRC:

apt install sysvinit-core openrc elogind libpam-elogind orphan-sysvinit-scripts

Sysv:

apt install sysvinit-core libpam-elogind orphan-sysvinit-scripts 

## Set Timezone

Run the follwing command and go through the steps

dpkg-reconfigure tzdata

## Network Configuration

This step depends on which networking tool you plan on using. I’ll use ifupdown (I’m a simple man, so it’s what I use) and network manager as examples.

  • Using ifupdown: install the ifupdown package, along with wpasupplicant and crda if you’re using wifi.
apt install ifupdown wpasupplicant crda

Next, if the system you’re doing this from does not use ifupdown, and you didn’t copy its /etc/network/interfaces file to the chroot, you will need to create the proper file. You can refer to my ifupdown guide on how to configure /etc/network/interfaces for either wired or wireless networks, or both, in detail, but for now, here’s a quick way to setup a basic ethernet connection with a dynamic IP address:

Find your interface’s name with

find /sys/class/net

Wired networks usually start with ‘enp’ (eg: enp1s0)

Add the following lines to /etc/network/interfaces, with your prefered text editor

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug enp1s0
iface enp1s0 inet dhcp
  • Using NetworkManager:

Note that I highly recommend installing a notification program alongside it, to avoid gnome’s notification-daemon from getting installed (unless you’re planning on installing gnome later on, that is). I recommend either dunst or xfce4-notifyd.

apt install network-manager dunst

If you need NM’s applet in a panel/status bar, substitute network-manager for network-manager-gnome.

  • Whether you’re using ifupdown or network manager, make sure you install the proper firmware for your wireless device (if you use any) before you continue.

## Hostname and hosts file

  • Choose a hostname for your system, this can be whatever you want. Substitute $EDITOR for your editor of choice, and $HOSTNAME for your hostname.
echo $HOSTNAME > /etc/hostname
  • Fill in the hosts file.
$EDITOR /etc/hosts

This is a basic hosts file. Note: if you installed network-manager, you will simply need to add the following second line, under the first one.

127.0.0.1   localhost
127.0.1.1   $HOSTNAME

# IPv6
::1         localhost ip6-localhost ip6-loopback
ff02::1     ip6-allnodes
ff02::2     ip6-allrouters

## Locales and Keyboard configuration

  • Install the locales package, then configure
apt install locales
dpkg-reconfigure locales
  • Configuring your keyboard (required only if you’re not planning on using the default en_US keymap)
apt install console-setup
dpkg-reconfigure keyboard-configuration

You may not want to run dpkg-reconfigure keyboard-configuration. I find it more trouble than it’s worth and it seems to me like it is not required, though it’s mentioned in most guides.

Certain changes to the keymap will only take effect once rebooted into the new install.

## Users, passwords and authentication

  • Start by creating a password for the root account. This can (and should) be locked later on with passwd -l root
passwd
  • Setting up your default user:
useradd -m username
passwd username
  • Add the user to necessary groups, and give it the proper interactive shell. Debian uses bash as its default interactive shell, but you can choose whatever you like (install it first, of course).
usermod -aG cdrom,floppy,audio,dip,video,plugdev,netdev username
usermod -s /bin/bash username
  • Next, you need to decide if you want sudo or doas in order to elevate your user’s privileges for updates, etc… This is your choice, though I personally prefer doas.

For doas:

apt install doas

then create the doas.conf file and permit your user

touch /etc/doas.conf
echo permit username > /etc/doas.conf

For sudo:

apt install sudo
usermod -aG sudo username

Debian provides a pre-configured sudoers file, and you probably don’t need to change anything, but it’s wise to verify that the line under “allow members of group sudo …” is not commented out.

cat /etc/sudoers

Look at the output, and if the line is commented out, use the visudo command and uncomment it.

## Setting up the bootloader

Here we use grub, but other bootloaders can be chosen.

  • For EFI systems
mkdir /boot/efi
mount /dev/sdX1 /boot/efi
apt install grub-efi-amd64
grub-install --target=x86_64-efi --efi-directory=/boot/efi
update-grub
  • For legacy (non-EFI) systems
apt install grub-pc
grub-install /dev/sda   (swap sda for the device on which Debian has been installed)
update-grub

## Finalizing

  • Run apt clean for good measure.
  • That’s it. You now have a basic cli install, exit the chroot with the exit command, reboot your system, and you can now start installing whatever packages you want.

## Seeing it in action

This video highlights the process in action. Here, the install is for UEFI systems, ifupdown/wpasupplicant for networking, uses OpenRC as init and doas instead of sudo.


Relevant posts: