Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save camillanapoles/0dd408a8aaecb52ed96bfeb39af9b392 to your computer and use it in GitHub Desktop.

Select an option

Save camillanapoles/0dd408a8aaecb52ed96bfeb39af9b392 to your computer and use it in GitHub Desktop.
Instructions how to install Debian using debootstrap

Instructions how to install debian using debootstrap. Below instructions were verified to work with debootstrapping Debian 11.

Table of contents

  1. Conventions
  2. Essential steps
    1. Install debootstrap
    2. Set up filesystem for Debian
    3. Mount filesystem
    4. Install base system
    5. Chroot into installed base system
    6. Set up editor
    7. Edit fstab file
    8. Configure apt sources
    9. Choose timezone
    10. Configure locales
    11. Install kernel
    12. Install firmware
    13. Set hostname
    14. Configure networking
    15. Install boot loader
    16. Set root's password
  3. Optional steps
    1. Install ssh-server
    2. Create an unprivileged user
    3. Install additional software
    4. Configure console keyboard layout
  4. Finish installation
    1. Precautionary reboot
      1. Boot the old system by default
      2. Make kernel reboot after kernel panic
      3. Delayed reboot after startup
      4. On the next boot, boot the new system once
    2. Install boot loader to disk
    3. Exit chroot
    4. Unmount /mnt
    5. Reboot into the new system

Conventions

  • /dev/PARTITION: replace it with the partition where Debian is to be installed e.g. /dev/sda2 or /dev/sdb1
  • /mnt: mountpoint for /dev/PARTITION, you can change it to something else

Essential steps

Install debootstrap

Prepare work directory, e.g:

cd /tmp

Go https://deb.debian.org/debian/pool/main/d/debootstrap/?C=M;O=D and download latest debootstrap_X.X.X_all.deb, e.g.:

wget 'https://deb.debian.org/debian/pool/main/d/debootstrap/debootstrap_1.0.124_all.deb'

Then install it:

dpkg -i debootstrap_*.*.*_all.deb

Set up filesystem for Debian

E.g.

mkfs.ext4 /dev/PARTITION

Mount filesystem

mount /dev/PARTITION /mnt

Install base system

Usage: debootstrap --arch ARCH RELEASE DIR MIRROR E.g.

debootstrap --arch amd64 stable /mnt https://deb.debian.org/debian

Chroot into installed base system

mount --make-rslave --rbind /proc /mnt/proc
mount --make-rslave --rbind /sys /mnt/sys
mount --make-rslave --rbind /dev /mnt/dev
mount --make-rslave --rbind /run /mnt/run
chroot /mnt /bin/bash

Set up editor

  • nano: should already be there as default
  • vim:
    apt install vim
    update-alternatives --config editor
    E.g. I chose /usr/bin/vim.basic.
  • others: proceed analogously to vim

Edit fstab file

It is not recommended to name partitions by kernel name e.g. /dev/sda1, as they may change. One of the alternatives is UUID. To get UUID of /dev/PARTITION you can use:

lsblk -f /dev/PARTITION

To edit /etc/fstab use:

editor /etc/fstab

E.g. /etc/fstab based on the one produced by Debian 11 installer:

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# systemd generates mount units based on this file, see systemd.mount(5).
# Please run 'systemctl daemon-reload' after making changes here.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
UUID=f80d9192-2bd3-466b-8c5f-ac10614e1d3d /               ext4    errors=remount-ro 0       1

To make life easier you can do:

lsblk -f /dev/PARTITION >> /etc/fstab
editor /etc/fstab

For more details see: man fstab

Configure apt sources

Fill /etc/apt/sources.list:

apt install lsb-release
CODENAME=$(lsb_release --codename --short)
cat > /etc/apt/sources.list << HEREDOC
deb https://deb.debian.org/debian/ $CODENAME main contrib non-free
deb-src https://deb.debian.org/debian/ $CODENAME main contrib non-free

deb https://security.debian.org/debian-security $CODENAME-security main contrib non-free
deb-src https://security.debian.org/debian-security $CODENAME-security main contrib non-free

deb https://deb.debian.org/debian/ $CODENAME-updates main contrib non-free
deb-src https://deb.debian.org/debian/ $CODENAME-updates main contrib non-free
HEREDOC

Then check if everything is as you like:

editor /etc/apt/sources.list

Finally, run:

apt update

For more details see: https://wiki.debian.org/SourcesList

Choose timezone

dpkg-reconfigure tzdata

Configure locales

apt install locales
dpkg-reconfigure locales

E.g. select en_US.UTF-8, then C.UTF-8.

Install kernel

To boot the system you will need Linux kernel and a boot loader. You can search available kernel images by running:

apt search linux-image

Then install your chosen kernel image, e.g.:

apt install linux-image-amd64

Install firmware

apt install firmware-linux

Set hostname

Set hostname e.g.:

echo "MY_HOSTNAME" > /etc/hostname

where MY_HOSTNAME is the hostname you want to set.

Then update /etc/hosts:

cat > /etc/hosts << HEREDOC
127.0.0.1 localhost
127.0.1.1 $(cat /etc/hostname)

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
HEREDOC

Configure networking

Simpler option: NetworkManager

apt install network-manager

For more details see: https://wiki.debian.org/NetworkManager

Other option: network interfaces

Warning: I had trouble with physically disconnecting and reconnecting Ethernet cables while using this method. With NetworkManager everything works seamlessly.

First take a look at examples in /usr/share/doc/ifupdown/examples/network-interfaces and then write your config:

editor /etc/network/interfaces

or create drop-in files in /etc/network/interfaces.d/ directory and write your configs there.

Enter your nameserver(s) and search directives in /etc/resolv.conf:

editor /etc/resolv.conf

A simple example /etc/resolv.conf:

search hqdom.local
nameserver 1.1.1.1
nameserver 9.9.9.9

For more detailed instructions see: https://wiki.debian.org/NetworkConfiguration

Install boot loader

apt install grub2

This will not overwrite the current grub installation on disk, we will do it at the very end of these instructions.

Set root's password

passwd

Optional steps

Install ssh-server

apt install openssh-server

Remember that an unprivileged user has to be created because, by default ssh'ing onto root is forbidden.

Create an unprivileged user

Create user and set password:

useradd USERNAME -m
passwd USERNAME

Replace USERNAME with username of an user you want to create.

(Optional) If you intend to use sudo:

  • Install sudo:
    apt install sudo
  • Add the new user to group sudo:
    usermod -aG sudo USERNAME

Install additional software

E.g.

tasksel install standard

To get list of all available tasks use:

tasksel --list-tasks

Configure console keyboard layout

apt install console-setup console-setup-linux

To change layout:

dpkg-reconfigure keyboard-configuration
systemctl restart console-setup

E.g. I select Generic 105-key PC (intl.) > Polish - Polish (programmer Dvorak).

Finish installation

Precautionary reboot

It would be great if the machine rebooted into the old system when something goes wrong with the new system. This is attainable to some degree.

If you can reboot machine physically or remotely if e.g. kernel malfunctions and have access to grub menu during boot, then below steps are unnecessary for you.

Boot the old system by default

First, set GRUB_DEFAULT to saved:

editor /etc/default/grub

or just run:

sed -i 's/^GRUB_DEFAULT=.*/GRUB_DEFAULT=saved/' /etc/default/grub

After that:

update-grub

Now, list all entries in grub menu:

grep -Pi "menu.* '" /boot/grub/grub.cfg | sed "s/' .*/'/g" | ( \
    IFS=""; A=-1; B=0; \
    while read x; do \
        echo "$x" | grep "^\s" -q && \
            { echo -e "$A>$B\t$x"; B=$((B+1)); } || \
            { A=$((A+1)); B=0; echo -e "$A\t$x"; }; \
    done)

E.g. output:

0   menuentry 'Debian GNU/Linux'
1   submenu 'Advanced options for Debian GNU/Linux'
1>0     menuentry 'Debian GNU/Linux, with Linux 5.10.0-9-amd64'
1>1     menuentry 'Debian GNU/Linux, with Linux 5.10.0-9-amd64 (recovery mode)'
2   menuentry 'Debian GNU/Linux 10 (buster) (on /dev/sda1)'
3   submenu 'Advanced options for Debian GNU/Linux 10 (buster) (on /dev/sda1)'
3>0     menuentry 'Debian GNU/Linux (on /dev/sda1)'
3>1     menuentry 'Debian GNU/Linux, with Linux 4.19.0-18-amd64 (on /dev/sda1)'
3>2     menuentry 'Debian GNU/Linux, with Linux 4.19.0-18-amd64 (recovery mode) (on /dev/sda1)'
3>3     menuentry 'Debian GNU/Linux, with Linux 4.19.0-11-amd64 (on /dev/sda1)'
3>4     menuentry 'Debian GNU/Linux, with Linux 4.19.0-11-amd64 (recovery mode) (on /dev/sda1)'

Now we want grub to always boot the old system by default.

To set default system use grub-set-default NUM where NUM is the number from the first column e.g.

  • For Debian GNU/Linux, with Linux 4.19.0-18-amd64 (on /dev/sda1) use:
    grub-set-default 3>1
  • For Debian GNU/Linux 10 (buster) (on /dev/sda1) use:
    grub-set-default 2

Remember to change this if the new system boots successfully and you want it to be the default system e.g. grub-set-defalt 0

For more details see: https://wiki.debian.org/GrubReboot#With_GRUB_v2

Make kernel reboot after kernel panic

Now tell kernel to reboot after 10 seconds if kernel panic happens.

Edit /etc/default/grub and append panic=10 to GRUB_CMDLINE_LINUX e.g. GRUB_CMDLINE_LINUX="panic=10":

editor /etc/default/grub

Then

update-grub

Delayed reboot after startup

To set the system to reboot after 30 seconds if something goes wrong, create systemd service and timer to trigger it and enable the timer:

cat > /etc/systemd/system/precautionary-reboot.service << 'HEREDOC'
[Service]
Type=oneshot
ExecStart=/bin/systemctl reboot
HEREDOC
cat > /etc/systemd/system/precautionary-reboot.timer << 'HEREDOC'
[Timer]
OnBootSec=30sec
AccuracySec=1sec

[Install]
WantedBy=timers.target
HEREDOC
systemctl enable precautionary-reboot.timer

Remember to disable this if the new system boots successfully: systemctl disable --now precautionary-reboot.timer

On the next boot, boot the new system once

Now tell GRUB to choose (only on the next boot) the new system using grub-reboot NUM e.g. booting Debian GNU/Linux:

grub-reboot 0

For more details see: https://wiki.debian.org/GrubReboot#With_GRUB_v2

Install boot loader to disk

Warning: this step overwrites the current grub installation

update-grub && grub-install --root-directory / /dev/DISK

where /dev/DISK is the disk on which you want grub to be installed e.g. /dev/sda.

Exit chroot

exit

Unmount /mnt

umount -R /mnt

Reboot into the new system

reboot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment