How to install Debian from Debian¶
Using LVM and debootstrap¶
Despite the title, this installation method should work for any Debian derivatives including Ubuntu.
This tutorial explains how to re-install a Debian based distribution on a running system. This has the advantage that we do not need to use the Debian Installer and we can minimize the downtime to that of a reboot. It is also especially useful if we want to reuse data on existing logical volumes, like virtual machine disk images on a hypervisor.
Requirements¶
This guide requires that the system was installed in EFI mode and the usage of the following partition and LVM setup.
NAME TYPE MOUNTPOINT
sda disk
├─sda1 part /boot/efi
└─sda2 part
├─vg0-root lvm /
├─vg0-var lvm /var
└─vg0-varlog lvm /var/log
We have a single disk with two partitions, containing the ESP (EFI System Partition) and the LVM physical volume.
This guide also assumes we have 3 separate logical volumes for the mount points /
, /var
and /var/log
and that we do not use UUIDs for the ext4
file-systems in /etc/fstab
as shown below:
/dev/mapper/vg0-root / ext4 noatime,nodiratime,errors=remount-ro 0 1
UUID=5E4A-9F35 /boot/efi vfat umask=0077 0 1
/dev/mapper/vg0-var /var ext4 noatime,nodiratime 0 2
/dev/mapper/vg0-varlog /var/log ext4 noatime,nodiratime 0 2
Installation¶
First rename the existing LVs containing the running system:
lvrename /dev/vg0/var /dev/vg0/var2
lvrename /dev/vg0/varlog /dev/vg0/varlog2
lvrename /dev/vg0/root /dev/vg0/root2
Then create new LVs to contain the new system with initial names of our running system:
lvcreate -L 5G -n root vg0 -y
lvcreate -L 5G -n var vg0 -y
lvcreate -L 2G -n varlog vg0 -y
mkfs.ext4 /dev/vg0/root
mkfs.ext4 /dev/vg0/var
mkfs.ext4 /dev/vg0/varlog
Mount the LVs:
mount /dev/vg0/root /mnt
mkdir -p /mnt/var
mount /dev/vg0/var /mnt/var
mkdir /mnt/var/log
mount /dev/vg0/varlog /mnt/var/log
The next step is to bootstrap a minimal system using debootstrap
:
debootstrap buster /mnt http://debian.ethz.ch/debian/
Before we chroot into the new system, we need to mount some special file-systems provided by the Kernel on our running system:
mount --bind /dev /mnt/dev
mount -t sysfs /sys /mnt/sys
mount -t proc none /mnt/proc
mount -t devpts devpts -o noexec,nosuid,gid=5,mode=620 /mnt/dev/pts
mount --bind /run /mnt/run
At this point we can already copy over some configuration files. Here are the files we need on a managed computer at the D-PHYS, adapt this for your setup:
cp -p /etc/apt/sources.list /mnt/etc/apt/sources.list
cp -p /etc/gai.conf /mnt/etc/
cp -p /etc/apt/apt.conf.d/90local /mnt/etc/apt/apt.conf.d/90local
cp -p /etc/default/grub /mnt/etc/default/grub
cp -p /etc/network/interfaces /mnt/etc/network/interfaces
cp -p /etc/systemd/network/* /mnt/etc/systemd/network/
cp -p /etc/hostname /mnt/etc/hostname
cp -rp /root/.ssh /mnt/root/
cp -rp /etc/ssh /mnt/etc/
cp -p /etc/fstab /mnt/etc/
Now we chroot into the new system and install the rest of the required packages, like the Kernel and grub. When grub asks where it should be installed, select nothing and choose not to install grub at this time. Grub should already be installed correctly.
chroot /mnt /bin/bash
apt-get update
apt-get upgrade -y
apt-get install linux-image-amd64 -y
apt-get install locales mdadm ssh dbus firmware-linux firmware-linux-nonfree -y
apt-get install grub2 lvm2 -y
apt-get install python-minimal python-apt vim -y
You should now configure your locales and time zone data:
dpkg-reconfigure locales
dpkg-reconfigure tzdata
and set a root password, for example using a hash:
usermod -p '<sha512-hash>' root
If you use systemd-networkd
you need to enable it now:
systemctl enable systemd-networkd.service
systemctl enable systemd-resolved.service
rm /etc/resolv.conf
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
To exit the chroot environment press Ctrl-d
or enter:
exit
Now back on the initial system, we need to configure grub
:
mkdir /mnt/boot/efi
cp -rp /boot/grub/* /mnt/boot/grub/
Replace the root
LV's file-system UUID (see lsblk -f
) and LV UUID (lvdisplay
) in the following files:
/mnt/boot/grub/grub.cfg
/boot/efi/EFI/debian/grub.cfg
For example using sed:
sed -i 's/OLDFSUUID/NEWFSUUID/g' /mnt/boot/grub/grub.cfg
sed -i 's/OLDLVUUID/NEWLVUUID/g' /mnt/boot/grub/grub.cfg
sed -i 's/OLDFSUUID/NEWFSUUID/g' /boot/efi/EFI/debian/grub.cfg
sed -i 's/OLDLVUUID/NEWLVUUID/g' /boot/efi/EFI/debian/grub.cfg
Now we can unmount our target system at /mnt
:
umount --recursive /mnt
You should also update /etc/fstab
of the initial system to the names of the renamed LVs. Just in case should you encounter any problems and want to switch back to old system in /boot/efi/EFI/debian/grub.cfg
.
Finally reboot into the new system:
reboot
Using netboot installer from disk¶
This guide shows how to manually set up a debian netboot installer on a separate disk that could also be installed into another system to boot from.
Alternatively this can also be done on the disk where the system is currently running. In that case the existing grub configuration needs to be modified as shown here.
Installation¶
Install and mount the disk to prepare with the installer images:
mkfs.ext4 /dev/sdb
mount /dev/sdb /mnt
cd /mnt
mkdir -p boot/newinstall
wget https://debian.ethz.ch/debian/dists/bookworm/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz -O boot/newinstall/initrd.gz
wget https://debian.ethz.ch/debian/dists/bookworm/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux -O boot/newinstall/linux
Optionally create and configure a preseed.cfg
file for automatic installation and inject it into the initrd:
vim preseed.cfg
gunzip /mnt/boot/newinstall/initrd.gz
echo preseed.cfg | cpio -H newc -o -A -F /mnt/boot/newinstall/initrd
gzip /mnt/boot/newinstall/initrd
Install and configure the extlinux bootloader:
apt install extlinux
extlinux --install /mnt
cat > /mnt/syslinux.cfg << EOF
PROMPT 0
TIMEOUT 0
DEFAULT linux
LABEL linux
LINUX /boot/newinstall/linux
APPEND root=/dev/sda preseed/file=/preseed.cfg
INITRD /boot/newinstall/initrd.gz
EOF
sync