Instructions how to install debian using debootstrap. Below instructions were verified to work with debootstrapping Debian 11.
- Conventions
- Essential steps
- Install debootstrap
- Set up filesystem for Debian
- Mount filesystem
- Install base system
- Chroot into installed base system
- Set up editor
- Edit fstab file
- Configure apt sources
- Choose timezone
- Configure locales
- Install kernel
- Install firmware
- Set hostname
- Configure networking
- Install boot loader
- Set root's password
- Optional steps
- Finish installation
/dev/PARTITION: replace it with the partition where Debian is to be installed e.g./dev/sda2or/dev/sdb1/mnt: mountpoint for/dev/PARTITION, you can change it to something else
Prepare work directory, e.g:
cd /tmpGo 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.debE.g.
mkfs.ext4 /dev/PARTITIONmount /dev/PARTITION /mntUsage: debootstrap --arch ARCH RELEASE DIR MIRROR
E.g.
debootstrap --arch amd64 stable /mnt https://deb.debian.org/debianmount --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/bashnano: should already be there as defaultvim:E.g. I choseapt install vim update-alternatives --config editor
/usr/bin/vim.basic.- others: proceed analogously to
vim
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/PARTITIONTo edit /etc/fstab use:
editor /etc/fstabE.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/fstabFor more details see: man fstab
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
HEREDOCThen check if everything is as you like:
editor /etc/apt/sources.listFinally, run:
apt updateFor more details see: https://wiki.debian.org/SourcesList
dpkg-reconfigure tzdata
apt install locales
dpkg-reconfigure localesE.g. select en_US.UTF-8, then C.UTF-8.
To boot the system you will need Linux kernel and a boot loader. You can search available kernel images by running:
apt search linux-imageThen install your chosen kernel image, e.g.:
apt install linux-image-amd64apt install firmware-linuxSet hostname e.g.:
echo "MY_HOSTNAME" > /etc/hostnamewhere 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
HEREDOCapt install network-managerFor more details see: https://wiki.debian.org/NetworkManager
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/interfacesor 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
apt install grub2This will not overwrite the current grub installation on disk, we will do it at the very end of these instructions.
passwdapt install openssh-serverRemember that an unprivileged user has to be created because, by default ssh'ing onto root is forbidden.
Create user and set password:
useradd USERNAME -m
passwd USERNAMEReplace 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
E.g.
tasksel install standardTo get list of all available tasks use:
tasksel --list-tasksapt install console-setup console-setup-linuxTo change layout:
dpkg-reconfigure keyboard-configuration
systemctl restart console-setupE.g. I select Generic 105-key PC (intl.) > Polish - Polish (programmer Dvorak).
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.
First, set GRUB_DEFAULT to saved:
editor /etc/default/grubor just run:
sed -i 's/^GRUB_DEFAULT=.*/GRUB_DEFAULT=saved/' /etc/default/grubAfter that:
update-grubNow, 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
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/grubThen
update-grubTo 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.timerRemember to disable this if the new system boots successfully: systemctl disable --now precautionary-reboot.timer
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 0For more details see: https://wiki.debian.org/GrubReboot#With_GRUB_v2
Warning: this step overwrites the current grub installation
update-grub && grub-install --root-directory / /dev/DISKwhere /dev/DISK is the disk on which you want grub to be installed e.g. /dev/sda.
exitumount -R /mntreboot