Installing NixOS on a Kimsufi
December 24, 2015
December 24, 2015
Sidenote: yes, I’m absolutely doing this on a December 24.
I recently obtained a Kimsufi server[1] and wanted to install NixOS on it. Though the web installation wizard doesn’t know about NixOS, thus requiring some more manual steps to install it.
This blog post is an (up-to-date) mix of How to install NixOS from Linux and Install NixOS on a So you Start dedicated server articles.
I started from an Arch Linux installation (available on the web installation wizard). If you have another system running, you can skip this step.
The idea is just to SSH into a preconfigured system to get the network information, namely the hostname, IPv4 and IPv6 adresses, netmasks and gateways, and optionally DNS servers.
You can find the hostname in the standard /etc/hostname
, and IP
information in /root/.ovhrc
and /etc/netctl/ovh_net_eth0
.
# /root/.ovhrc
DNS_IP="{{ IPV4_DNS }}"
DNS_IPV6="{{ IPV6_DNS }}"
IPV6ADDR="{{ IPV6_ADDR }}"
IPV6GW="{{ IPV6_GW }}"
IPV6NETMASK="{{ IPV6_NETMASK }}"
SERVERNAME="{{ HOSTNAME }}.whatever.eu"
# /etc/netctl/ovh_net_eth0
Address=('{{ IPV4_ADDR }}/{{ IPV4_NETMASK }}')
Gateway=('{{ IPV4_GW }}')
DNS=('{{ IPV4_DNS }}')
Address6=('{{ IPV6_ADDR }}/{{ IPV6_NETMASK }}')
IPCustom=('-6 route add {{ IPV6_GW }} dev eth0' '-6 route add default via {{ IPV6_GW }}
You will need those when creating your NixOS configuration.
We cannot specify a custom ISO to boot in, so we need to boot in rescue mode and replicate the NixOS ISO system in order to do the regular installation steps.
After restarting in rescue mode, you’ll receive a mail with the SSH credentials. Once there, execute the following steps:
In rescue mode the public network interface is eth0
but in NixOS, with
systemd, it’s a different name, and you’ll need to explicitly specify it
for the network configuration. For this, run the following command:
udevadm test-builtin net_id /sys/class/net/eth0 2> /dev/null
Which will output:
ID_NET_NAME_PATH={{ NETIF }}
While this step is usually done in the regular installation procedure, we need to do this before because faking the NixOS ISO system requires more space than available in rescue mode (at least in case of my instance), so I need to prepare a small (2GB) partition for this.
fdisk /dev/sda
Personally I made 4 partitions, one of 30GB for the system, one for the home, and at the end 2GB for swap, and 2GB to extract NixOS.
mkfs.ext4 -L nixos /dev/sda1
mkfs.ext4 -L home /dev/sda2
mkswap -L swap /dev/sda3
mkfs.ext4 -L nixos-rescue /dev/sda4
The following commands assume this layout, obviously tweak them for your own needs.
We create an image
directory to mount the installation ISO in, and a
rescue
directory to mount the 2GB nixos-rescue
partition and
replicate the ISO system in.
mkdir image rescue
mount /dev/disk/by-label/nixos-rescue rescue
mkdir rescue/nix
Get the ISO URL of the NixOS release you want to install, see the download page.
In my case I fetched the latest unstable at this date:
wget 'https://nixos.org/releases/nixos/unstable/nixos-16.03pre73316.93d8671/nixos-minimal-16.03pre73316.93d8671-x86_64-linux.iso'
mount -o loop nixos-minimal-16.03pre73316.93d8671-x86_64-linux.iso image
To extract the store from the ISO to the rescue system, we need to get
the squashfs-tools
package, then extract it:
apt-get install squashfs-tools
unsquashfs -d rescue/nix/store image/nix-store.squashfs '*'
We then recreate the needed FHS entries and mount bind or copy whatever is needed from the host system:
cd rescue
mkdir -p etc dev proc sys
mount --bind /dev dev
mount --bind /proc proc
mount --bind /sys sys
Also take note of the content of /etc/resolv.conf
to manually copy it
after chroot
.
chroot
in the installation systemFirst need to find the right path for init
and bash
:
INIT=$(find . -type f -path '*nixos*/init')
BASH=$(find . -type f -path '*/bin/bash' | tail -n 1)
# See <https://discourse.nixos.org/t/nixos-on-ovh-kimsufi-cloning-builder-process-operation-not-permitted/1494/2>
find . -type f -path '*-nix.conf' | xargs sed -i 's/sandbox = true/sandbox = false/'
Then modify the init script to execute bash
instead of systemd
:
sed -i "s,exec systemd,exec /$BASH," "$INIT"
Now ready to chroot
:
chroot . /$INIT
Just after, restore the /etc/resolv.conf
.
You can now install your system as if you were in the installation ISO:
mount /dev/disk/by-label/nixos /mnt
mkdir /mnt/home
mount /dev/disk/by-label/home /mnt/home
swapon /dev/disk/by-label/swap
nixos-generate-config --root /mnt
Then edit the configuration to reflect the OVH network settings, plus usual stuff like boot loader, locale, timezone, users:
nix-env -i vim
vim /mnt/etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
# ...
networking = {
hostName = "{{ HOSTNAME }}";
interfaces.{{ NETIF }} = {
ip4 = [ { address = "{{ IPV4_ADDR }}"; prefixLength = {{ IPV4_NETMASK }}; } ];
ip6 = [ { address = "{{ IPV6_ADDR }}"; prefixLength = {{ IPV6_NETMASK }}; } ];
};
defaultGateway = "{{ IPV4_GW }}";
defaultGateway6 = "{{ IPV6_GW }}";
nameservers = [ "{{ IPV4_DNS }}", "{{ IPV6_DNS }}" ];
};
# ...
}
I like to have those settings in an external file like
/etc/nixos/ovh-configuration.nix
and add it to the imports
list.
You’re then ready to install the system:
nixos-install
If you want to execute more commands in your new system, like setting passwords for new users:
nixos-install --chroot
Then you can unmount everything and exit:
umount -R /mnt
exit
From the management panel, define the hard disk as default boot device, and reboot the system. You should be able to SSH with the user/password you created previously.
If your server doesn’t go up, you can’t connect, or whatever, boot back in rescue mode, and look what happened in the system logs with:
mount /dev/disk/by-label/nixos /mnt
journalctl -D /mnt/var/log/journal
Because I moved from France (where I have a home server) to Quebec, and here we have a bandwidth consumption limit, and I don’t feel like hosting a home server behind a limited connection, especially when sharing this connection with roommates! Hence the investment in renting a dedicated server. ↩︎