Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add instructions on how to install NixOS on Media Temple #95

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions MediaTemple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# NixOS on Media Temple

On Media Temple we can install NixOS on Ubuntu servers by using a custom infect script.

## Add a new server

1. Click on `Add New Service` and select `Self Managed VPS`.
1. Select appropriate server resources (e.g. 2 CPU, 4GB RAM and 100GB storage) and tick `No control panel`.
1. After order has been processed you will need to finish the installation (selecting Ubuntu
version, setting username and password)

## Infect Ubuntu 20.04

After executing the infect script (`bash infect.sh`) you will need to modify the
`hardware-configuration.nix` file. The script will stop and you will need to do it
manually. You will need to remove all `squashfs` and `vfat` (efi boot) entries.
The automatically generated config will look something like this:

```
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:

{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];

boot.initrd.availableKernelModules = [ "ata_piix" "virtio_pci" "virtio_scsi" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];

fileSystems."/" =
{ device = "/dev/disk/by-uuid/e46da1b8-55a0-4df9-842e-8d80c3a22ffc";
fsType = "ext4";
};

fileSystems."/snap/snapd/12883" =
{ device = "/var/lib/snapd/snaps/snapd_12883.snap";
fsType = "squashfs";
options = [ "loop" ];
};

fileSystems."/snap/core20/1081" =
{ device = "/var/lib/snapd/snaps/core20_1081.snap";
fsType = "squashfs";
options = [ "loop" ];
};

fileSystems."/boot/efi" =
{ device = "/dev/disk/by-uuid/7341-10DC";
fsType = "vfat";
};

fileSystems."/snap/lxd/21545" =
{ device = "/var/lib/snapd/snaps/lxd_21545.snap";
fsType = "squashfs";
options = [ "loop" ];
};

fileSystems."/snap/snapd/14549" =
{ device = "/var/lib/snapd/snaps/snapd_14549.snap";
fsType = "squashfs";
options = [ "loop" ];
};

fileSystems."/snap/core20/1270" =
{ device = "/var/lib/snapd/snaps/core20_1270.snap";
fsType = "squashfs";
options = [ "loop" ];
};

fileSystems."/snap/lxd/21835" =
{ device = "/var/lib/snapd/snaps/lxd_21835.snap";
fsType = "squashfs";
options = [ "loop" ];
};

swapDevices = [ ];

}
```
It's also recommended to name `fileSystem."/"` device to `/dev/sda3` in case the server
gets relocated (disk UUID will change) and add `nvme` to `boot.initrd.kernelModules`.

How do I know it's `/dev/sda3` and not e.g. sda1 or sda2? Run `lsblk` and you will see
the correct pact. In our case:

```
root@ip:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 32.3M 1 loop /snap/snapd/12883
loop1 7:1 0 61.8M 1 loop /snap/core20/1081
loop2 7:2 0 67.3M 1 loop /snap/lxd/21545
loop3 7:3 0 43.4M 1 loop /snap/snapd/14549
loop4 7:4 0 61.9M 1 loop /snap/core20/1270
loop5 7:5 0 67.2M 1 loop /snap/lxd/21835
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 4M 0 part
├─sda2 8:2 0 106M 0 part /boot/efi
└─sda3 8:3 0 99.9G 0 part /
```

Optional:
- Add a bit of swap.
- Mount `/dev/sda2` partition on `/boot`

After you remove all the `squashfs` and the efi boot entries you will be left with:

```
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:

{
imports = [ ];

boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ];
boot.initrd.kernelModules = [ "nvme" ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];

fileSystems."/" =
{ device = "/dev/sda3";
fsType = "ext4";
};

fileSystems."/boot" =
{ device = "/dev/sda2";
fsType = "vfat";
};

swapDevices = [
{
device = "/swapfile";
size = 1024;
priority = 0;
}
];

}
```

The last few lines of infect output will look something like this:

```
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = "en_US.UTF-8",
LC_CTYPE = "UTF-8",
LANG = "C.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to a fallback locale ("C.UTF-8").
updating GRUB 2 menu...
installing the GRUB 2 boot loader on /dev/sda...
Installing for i386-pc platform.
/nix/store/jx1qj6fh98fnifslhllpcaqaia2nhxz5-grub-2.06/sbin/grub-install: warning: cannot open directory `/nix/store/jx1qj6fh98fnifslhllpcaqaia2nhxz5-grub-2.06/share/locale': No such file or directory.
Installation finished. No error reported.
```

Verify `/etc/nixos/*.nix` config files and make sure they are correct (especially IPs in
`configuration.nix`).

After reboot, you should be able to SSH to the server.
40 changes: 40 additions & 0 deletions MediaTemple/configuration.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{ pkgs, ... }: {
imports = [
./hardware-configuration.nix
# Including this by default now to avoid potential problems with missing kernel modules
<nixpkgs/nixos/modules/profiles/all-hardware.nix>
];
boot.loader.grub.device = "/dev/sda";
networking.useDHCP = false;
networking.enableIPv6 = false;
networking.interfaces.ens3.useDHCP = false;
networking.defaultGateway = "169.254.0.1";
networking.nameservers = [ "1.1.1.1" "1.0.0.1" ];
networking.interfaces.ens3 = {
ipv4.addresses = [
{ address = "1.2.3.4"; prefixLength = 32; } # Primary IP
{ address = "1.2.3.5"; prefixLength = 32; } # Secondary IP
];
ipv4.routes = [{
address = "169.254.0.1"; # IP of the gateway
prefixLength = 32;
}];
};

services.openssh = {
enable = true;
permitRootLogin = "prohibit-password";
passwordAuthentication = false;
};

# Set initial root password in case we need to use the rescue console.
# IMPORTANT: change the password!
users.users.root.initialPassword = "secret";

# IMPORTANT: replace with your own key(s)!
users.users.root.openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAAD..."
];

system.stateVersion = "21.05";
}
42 changes: 42 additions & 0 deletions MediaTemple/infect.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -e -o pipefail

# Add build group and user
groupadd nixbld -g 30000 || true
for i in {1..10}; do
useradd -c "Nix build user $i" -d /var/empty -g nixbld -G nixbld -M -N -r -s "$(which nologin)" "nixbld$i" || true
done

# Install NixOS
curl -L https://nixos.org/nix/install | sh
. /root/.nix-profile/etc/profile.d/nix.sh
nix-channel --add https://nixos.org/channels/nixos-21.05 nixpkgs
nix-channel --update

# Install NixOS installation tools, TODO: Make nicer
nix-env -iE "_: with import <nixpkgs/nixos> { configuration = {}; }; with config.system.build; [ nixos-generate-config ]"

# Set up configurations and install it in a profile
nixos-generate-config
echo "---"
echo "Remove the lxcfs (on Ubuntu 16.04) or squashfs (on Ubuntu 20.04 and 21.04) entry with nano"
sleep 5
nano /etc/nixos/hardware-configuration.nix
cp configuration.nix /etc/nixos
nix-env -p /nix/var/nix/profiles/system -f '<nixpkgs/nixos>' -I nixos-config=/etc/nixos/configuration.nix -iA system

# Set NixOS to boot and replace the original distro
touch /etc/NIXOS
cat > /etc/NIXOS_LUSTRATE <<EOF
etc/nixos
root/.nix-defexpr/channels
EOF

# Switch to NixOS OS
/nix/var/nix/profiles/system/bin/switch-to-configuration boot

echo "---"
echo "Verify all the settings and check if there were any problematic errors."
echo "If everything is OK, reboot"
echo ""
echo "Keep in mind that you have to deal with /old-root after reboot"