Install Debian on a VPS Provider without Debian Images
Recently, I came across a VPS provider that does not provide Debian images. This is rather annoying since I much prefer a fresh minimal install of Debian over a “minimal” Ubuntu image that still has a lot of stuff that I don’t want.
Naturally, I decided to install Debian anyways, and came up with an approach to do so.
If you are feeling particularly bold, you can try running my pre-made scripts that would convert a fresh Ubuntu install to a fresh Debian install.
To use the scripts, you should download either the UEFI version or the BIOS version, depending on whether your current OS is using BIOS or UEFI.
At the top of the script, change the variables to match your system
configuration. The most important one being BOOT_DRIVE
so that grub
would be
installed on the correct device.
The scripts will prompt you for a root password and SSH keys. Once the script finishes, the system will be rebooted and you should be able to SSH into the now-Debian machine as root via the SSH keys.
If you don’t feel like using the script, I am also providing manual instructions. This also explains how the scripts work.
Installing Debian to a chroot
First, we need to bootstrap a new install of Debian. To avoid conflicting with
the existing system, we will do it in a chroot
with a tool called
debootstrap
. You will also need the Debian archive’s keyring to verify
pacakges.
On a recent version of Ubuntu, you can probably install debootstrap
and
debian-archive-keyring
by running:
sudo apt install debootstrap debian-archive-keyring
On an older version, the keyring or debootstrap
might be out of date.
Instead, you can try downloading the .deb
packages from the Debian’s website:
These .deb
files can then be instaled with dpkg -i
. You should run
apt install -f
to install their dependencies.
Once this is done, you can install Debian into a chroot
by running:
debootstrap --arch amd64 buster /debian http://deb.debian.org/debian
The chroot will be located at /debian
. We will be installing buster
, the
latest release at this time, and the amd64
architecture, which is probably
what you want. If not, feel free to change these. Be sure to change all
subsequent operations.
Once debootstrap
finishes, a fresh copy of Debian will be ready.
Entering the chroot
We need to be able to access the real /dev
, /dev/pts
, /proc
and /sys
inside the chroot
. To do this, run:
for dir in /proc /sys /dev /dev/pts; do
mount --bind "$dir" "/debian/$dir"
done
We will also need to access the original root directory. Let’s put it at
/old_root
in the chroot
:
mkdir /debian/old_root
mount --bind / /debian/old_root
Let’s pretend that the OS is installed on /dev/sda
and this is the device that
needs to be bootable.
On UEFI systems, to avoid issues, we should unmount the EFI system partition
and remount it later inside the chroot. Run df | grep /boot/efi
to show
the device for the EFI system partition. As an example, we will use /dev/sda1
.
We then unmount it:
umount /boot/efi
We will likely need some configuration files, so let’s copy them:
cp /etc/resolv.conf /etc/fstab /debian/etc
Now, we can enter the chroot
by running:
chroot /debian /bin/bash
This should start bash
inside the new Debian chroot
.
Installing Basic Packages
We need to install a kernel, a grub
, the SSH server, and rsync
.
On a UEFI system, run:
apt install linux-image-amd64 grub-efi openssh-server rsync
On a BIOS system, run:
apt install linux-image-amd64 grub openssh-server rsync
To avoid network device issues, we tell Debian to continue using the old eth0
name for the network interface. To do this, we edit /etc/default/grub
to
and add net.ifnames=0 biosdevname=0
to GRUB_CMDLINE_LINUX
.
We can then set up the network by putting the following lines in
/etc/network/interfaces.d/eth0
:
allow-hotplug eth0
iface eth0 inet dhcp
You might want to change this if your system needs static IPs. For details, see the Debian Wiki.
You might also want to take this opportunity to set the root password by running
passwd
, and adding your SSH keys to /root/.ssh/authorized_keys
.
Removing the Old System
Our eventual goal is to install Debian into the original root filesystem (at
/old_root
inside the chroot
). To do this, we need to first get the old
system out of the way:
mkdir /old_root/old
mv old_root/* old_root/old
This will produce some errors, since we can’t move things like /dev
, /proc
,
/sys
, or even /old
iself. But these errors can be safely ignored.
Installing the Boot Loader
On a BIOS system, run:
grub-install /dev/sda
update-grub
On a UEFI system, run:
mkdir /boot/efi
mount /dev/sda1 /boot/efi
echo 'grub-efi-amd64 grub2/force_efi_extra_removable boolean true' | debconf-set-selections
grub-install /dev/sda
update-grub
mkdir -p /boot/efi/EFI/boot
cp /boot/efi/EFI/debian/grubx64.efi /boot/efi/EFI/boot/bootx64.efi
Here, we force grub
to be installed on the system as the fallback bootloader,
i.e. EFI/boot/bootx64.efi
. This is to avoid issues that can pop up if the
NVRAM which stores the boot menu is wiped or simply not imaged. While this
would prevent selection between multiple operating systems, I have yet to see
a multi-OS VPS, so it’s probably not a big deal.
Move Debian into position
Now, we just need to move Debian from the chroot
into the actual root
filesystem. This can be easily accomplished by running:
cd /
rsync -ax bin boot etc home lib lib32 lib64 libx32 media mnt opt root sbin srv tmp usr var old_root/
This should move all the important directories into /old_root
, which is the
actual root directory, while preserving permissions and everything.
Reboot
You can now run exit
to exit the chroot
, and reboot
to reboot into Debian.
If all goes well, you should be able to run ssh root@<your server>
to access
your new Debian server. After successfully booting, you can then delete the
old system as well as the chroot by running rm -rf /old
as root.
Conclusion
If you are successful, then you should now have a Debian VPS despite not having a pre-built image. If you run into issues, please comment and I will try to address them.
I hope you found this guide useful.