How to install any distrib on a Gandi VPS

Posted on Thu 18 November 2021 in blog

Currently Gandi VPS don't provide an image with Ubuntu Bionic, which is needed for example to install BBB. So I started an in-memory Ubuntu on top of an Ubuntu to install an Ubuntu...

If you land here from the future, and want to do the same, double check, Gandi may have already implemented an object storage allowing you to use any distrib, making the setup of alternative distribs way easier.

The same process could be used to install any Debian based distrib, or with some more modifications any other Linux distrib, don't hesitate to play around.

It can also be used to setup your own partition scheme or use encrypted partitions.


The probability you'll just brick your VPS once or twice before succeding is high. Don't do this on a VPS you care.

In case of failure, just drop the VPS and start fresh.

Last thing before starting, since very recently there's an easier alternative: you can use the « Rescue mode » and directly jump to the mkfs.ext4 /dev/xvda1 step.

OK, « en route » !!

The first step is to start a small Ubuntu (or Debian or whatever) in memory, so we'll be able to destroy the real one, for this I used, so SSH to your VPS and:

First get root:

sudo su -

Then we'll create a new root, in memory, for the temporary distrib:

mkdir /takeover
mount -t tmpfs tmpfs /takeover -o size=2G  # Fully in RAM as we'll umount / later.
apt update; apt-get install debootstrap busybox git build-essential
debootstrap --variant=minbase bionic /takeover/  # Any OS would do, it's just a temporary one from which we'll install the real one.

We could already chroot in it, but we'll prepare the ground for

wget -O /takeover/busybox
chmod a+x /takeover/busybox
git clone /tmp/
cp -a /tmp/* /takeover/
cd /takeover
gcc -static fakeinit.c -o fakeinit
chroot /takeover /usr/bin/apt install openssh-server
mkdir /takeover/run/sshd
cp usr/bin/passwd bin/  # need it here

OK everything is ready to "pivot" root filesystem:

sh  # Here Come The Dragons.

If everything goes well, we can now ssh to the in-memory sshd (on port 80), and kill all remaining things of the real underlying OS, umount everything, format it, and start fresh:

ssh -p80 root@your_host
pkill -9 -f systemd
# and all remaining process using kill -9 PID PID PID PID PID PID ... EXCEPT the SSH you're actually using!
mount | tac | grep old_root | cut -d' ' -f3 | xargs umount  # Umount old_root (may need to be ran multiple times)
mkfs.ext4 /dev/xvda1  # A clean filesystem for the new distrib
mount /dev/xvda1 /old_root/
echo nameserver > /etc/resolv.conf  # NEIN! NEIN!! NEIN!!! NEIN!!!!
apt install debootstrap

OK we destroyed everything from the old distrib, let's choose a new one:

debootstrap bionic /old_root/  # This is the OS and version you want to install, maybe it's not Ubuntu bionic!
mount -o bind /dev/ /old_root/dev/  # Prepare to chroot
mount -o bind /run/ /old_root/run/  # Prepare to chroot.
mount -o bind /sys/ /old_root/sys/  # Prepare to chroot..
mount -t proc none /old_root/proc/  # Prepare to chroot...
chroot /old_root/  # And we're back on disk!

Now we're back on disk, on the new distrib, we may have some configuration to do before rebooting like installing a kernel, changing root password, adding ssh keys, configuring grub, configuring network interfaces...

echo nameserver > /etc/resolv.conf  # Yes, again: we're not on the same root...
apt update
apt install linux-virtual openssh-server ifupdown
mkdir /root/.ssh/
wget -O /root/.ssh/authorized_keys  # Or your own keys, your choice.
passwd  # Set a root password, useful to connect via the emergency console.
printf "%s\n%s\n" 'auto eth0' 'iface eth0 inet dhcp' > /etc/network/interfaces  # Setup the network
# Setup /etc/fstab, if you want the UUID of the disk use `blkid`.
sync  # For good measure
reboot now

Now you can ssh on port 22 again, yes the fingerprint will have changed as we replaced the root filesystem we replaced /etc/ssh/key*, don't worry.