Logo Wael's Digital Garden

Install Debian or Ubuntu from within NixOS

Introduction#

I want to install Ubuntu but

  1. I don't want to boot into the Live installation media.
  2. I don't want the installer to screw up my bootloader, I want to be in control of that
  3. NixOS has debootsrap and other tools in the store, I don't really need to boot into an installer.

Getting the partitions up and running#

Create the ZFS volumes and mount them at /mnt/ubuntu.

sudo zfs create -o mountpoint=none olympus/system/ubuntu
sudo zfs create -o mountpoint=legacy olympus/system/ubuntu/root
sudo zfs create -o mountpoint=legacy olympus/system/ubuntu/var
sudo zfs create -o mountpoint=legacy olympus/system/ubuntu/nix
sudo zfs create -o mountpoint=legacy olympus/user/yl/ubuntu-home

And mount the volumes. I used NixOS to mount the volumes where they supposed to go at and within /mnt/ubuntu.

Installing the base#

Open a shell with the required packages from nixpkgs

nix shell nixpkgs-unstable#debootstrap

NOTE I used nixpkgs-unstable here because I needed the latest version of ubuntu and the stable version did not have what I needed.

sudo debootstrap oracular /mnt/ubuntu [http://archive.ubuntu.com/ubuntu/](http://archive.ubuntu.com/ubuntu/)

Run the second stage#

Make sure all Nix paths are swapped in the debootstrap

sudo sed -e 's:/nix/store/[^/]*/bin:/bin:g' -i /mnt/ubuntu/debootstrap/debootstrap

If the mirror file does not exist then create it. It should have existed but I think it's a problem with the installer failing

test -e /mnt/ubuntu/debootstrap/mirror || echo [http://archive.ubuntu.com/ubuntu/](http://archive.ubuntu.com/ubuntu/) | sudo tee /mnt/ubuntu/debootstrap/mirror

and run the second stage

sudo chroot /mnt/ubuntu /bin/bash -c "PATH=/usr/bin:/bin:/usr/sbin:/sbin /debootstrap/debootstrap --second-stage"

Configure apt, locale, timezone, hostname and password#

Important This steps is needed to remove errors about missing locale.

echo 'LANG="en_US.UTF-8"' | sudo tee /mnt/ubuntu/etc/default/locale
echo 'America/Los_Angeles' | sudo tee /mnt/ubuntu/etc/timezone
sudo cp /mnt/ubuntu/usr/share/zoneinfo/America/Los_Angeles /mnt/ubuntu/etc/localtime

Write /mnt/ubuntu/etc/apt/sources.list I used Gemini to generate it

## main repository
deb [http://archive.ubuntu.com/ubuntu](http://archive.ubuntu.com/ubuntu) oracular main restricted universe multiverse

## update repository
deb [http://archive.ubuntu.com/ubuntu](http://archive.ubuntu.com/ubuntu) oracular-updates main restricted universe multiverse

## backports repository
deb [http://archive.ubuntu.com/ubuntu](http://archive.ubuntu.com/ubuntu) oracular-backports main restricted universe multiverse

## security repository
deb [http://security.ubuntu.com/ubuntu](http://security.ubuntu.com/ubuntu) oracular-security main restricted universe multiverse

Chroot into the installation, and set the root password

sudo env -i chroot /mnt/ubuntu /bin/bash
passwd

Install the kernel#

sudo umount /mnt/ubuntu/boot

You should also mount required bind mounts

sudo mount --bind /dev /mnt/ubuntu/dev
sudo mount --bind /dev/pts /mnt/ubuntu/dev/pts
sudo mount -t proc proc /mnt/ubuntu/proc
sudo mount -t sysfs sys /mnt/ubuntu/sys

Then install the kernel within the chroot

sudo env -i chroot /mnt/ubuntu /bin/bash
apt-get update
apt-get install linux-image-generic

Finally move the files around to the actual boot location by moving the files out of /boot, mounting /boot and then copy the vmlinuz and the initrd.img over to the correct location. Be aware that the files are symlinks so you should copy what they point to instead.

Setup LUKS#

apt-get install cryptsetup-initramfs

Edit /mnt/ubuntu/etc/cryptsetup-initramfs/conf-hook and add this

KEYFILE_PATTERN=/etc/luks/*.keyfile

Setup the boot partition#

Booting from an encrypted boot partition requires changes to /etc/crypttab and re-generation of the initramfs

echo 'cryptroot UUID=5f4422ca-eb45-4532-931b-63225c2143d5 none luks,initramfs' | sudo tee /mnt/ubuntu/etc/crypttab

Re-generate the initramfs with

update-initramfs -u -k 6.11.0-9-generic

Setup SWAP key#

sudo mkdir -p /mnt/ubuntu/etc/luks
sudo dd if=/dev/random of=/mnt/ubuntu/etc/luks/cryptswap.keyfile bs=1 count=14336
sudo chmod 400 /mnt/ubuntu/etc/luks/cryptswap.keyfile
sudo cryptsetup luksAddKey --key-file=/dev/mapper/cryptkey /dev/disk/by-uuid/0249ea43-7216-4a9b-9c57-377f22c41bfc /mnt/ubuntu/etc/luks/cryptswap.keyfile

Add swap device to /etc/crypttab

sudo cat /mnt/ubuntu/etc/crypttab
# <target name> <source device>         <key file>      <options>
cryptswap       UUID=0249ea43-7216-4a9b-9c57-377f22c41bfc       /etc/luks/cryptswap.keyfile

ZFS#

Install the required initramfs package for booting from ZFS but you can't generate the initramfs without few files that are missing

sudo cp /etc/zfs/zpool.cache /mnt/ubuntu/etc/zfs/
apt-get install zfs-initramfs

And finally update the initramfs

update-initramfs -u -k 6.11.0-9-generic

Sources#