Article

Table of Contents
Theme:
Was this article helpful?

7  out of  8 found this helpful

Try Vultr Today with

$50 Free on Us!

Want to contribute?

You could earn up to $600 by adding new articles.

How to Install NixOS on a Vultr VPS

Author: Andrew Pan

Last Updated: Wed, Aug 11, 2021
Linux Guides System Admin

Install NixOS on Vultr

NixOS is a purely functional Linux distribution built on top of the Nix package manager. NixOS, and its module system, make it possible to build fully reproducible systems such that a configuration on a given machine, deployed on any other machine, will yield the same system state.

Installation Media

The public Vultr ISO library contains NixOS 20.09. If you are looking for a later version, you can add a NixOS ISO to Vultr. Choose a minimal x86_64 distribution from https://channels.nixos.org/. For example, version 21.05 would use this link:

https://channels.nixos.org/nixos-21.05/latest-nixos-minimal-x86_64-linux.iso

Deploy the Server

Go to the Vultr dashboard to deploy an instance. Choose any server plan and location.

For the Server Type selection, you have two options.

  • If you uploaded an ISO, you can find it in the Upload ISO tab.

  • Otherwise, find Vultr's NixOS in the ISO Library.

Select your desired version of NixOS, configure the server settings, and click Deploy Now.

Open the Console

After the VPS has finished launching, you should see it in your portal. Next, click the VPS entry and open the console (either a console icon or a 3-dot menu entry depending on your screen layout.)

You should be automatically logged in as the nixos account.

Login via SSH (optional)

If you prefer SSH instead of the Vultr Web Console, it's possible to temporarily authorize a SSH key for the nixos account during the installation by adding it to /home/nixos/.ssh/authorized_keys.

If you have your public SSH key uploaded to GitHub, for example, you can do the following:

$ mkdir ~/.ssh

$ curl -L https://github.com/<username>.keys >~/.ssh/authorized_keys

Log in via SSH as the nixos user.

Create the File System

  1. Run sudo -s to get a root shell for the following steps.

  2. Partition the disk using the parted CLI.

    # parted /dev/vda
    

    You should get output similar to this:

    GNU Parted 3.4
    
    Using /dev/vda
    
    Welcome to GNU Parted! Type' help' to view a list of commands.
    
    (parted)
    

    If you run an instance with less than 4 gigabytes of RAM, you will need a swap partition to complete the installation process successfully. In that case, use the following commands in the parted CLI.

    # mklabel msdos
    
    # mkpart primary 1MiB -1GiB
    
    # mkpart primary linux-swap -1GiB 100%
    

    Otherwise, create only the primary partition.

    # mklabel msdos
    
    # mkpart primary 1MiB 100%
    
  3. Once you're done with parted, issue the quit command. You should see the regular root prompt, similar to [root@nixos:/home/nixos]#.

  4. Format your new partition(s) with a filesystem.

    # mkfs.btrfs -L root /dev/vda1
    

    It's possible to use ext4 instead of btrfs:

    # mkfs.ext4 -L root /dev/vda1
    

    As of Linux 5.0, Btrfs is slower for most workloads than Ext4, but it has features that Ext4 lacks, such as snapshotting, enabled by its copy-on-write design. The decision is up to you.

  5. If you elected to add a swap partition, initialize it with the following.

    # mkswap -L swap /dev/vda2
    
    # swapon /dev/vda2
    
  6. Mount the disk.

    # mount /dev/disk/by-label/root /mnt
    

Configure NixOS

Now that you've gotten past booting and disk formatting, it's time to make decisions about configuration.

Nix Channels or Nix Flakes

Nix Channels are the original distribution mechanism for NixOS upgrades. WIth Nix Channels, a few key points are worth considering.

  • Version control of configuration files is not required

  • There is no "lockfile". A system configuration from two NixOS machines on the same channel version of NixOS may have different package versions and modules

  • Upgrades are handled by nix-channel --upgrade

Nix Flakes is the next generation of the Nix package manager. In contrast to Nix Channels, Nix Flakes have the following properties.

  • Version control of your configuration is required; typically Git.

  • Nixpkgs versions are pinned via a lockfile, flake.lock. When distributing a Flake-based system configuration across multiple machines, you are guaranteed always to get identical package versions and module behavior

  • Upgrades are handled by commands such as nix flake update

  • Nix Flakes comes with the next generation Nix CLI, which consolidates and simplifies Nix-related commands

With either channels or flakes, upgrades do not apply until a rebuild is triggered. For Channels, this entails running nixos-rebuild switch, while with Flakes, it's as simple as nixos-rebuild switch with the --flake flag.

However, as Nix Flakes is unstable, its behavior is subject to change.

Your decision boils down to two key points:

  • For maximum stability and if you don't mind slightly different software versions and occasional breakage across multiple virtual machines, use Nix Channels.

  • If you like experimenting and want perfect reproducibility across multiple machines, use Nix Flakes.

This guide provides a common configuration. A starter Flake atop of that configuration is also provided.

Generate the Initial Configuration

  1. Use this command to generate configuration derived from hardware information and your mounted disks.

    # nixos-generate-config --root /mnt
    
  2. Edit the newly generated configuration.

    # nano /mnt/etc/nixos/configuration.nix
    
  3. Change the following values. They may exist already in the configuration commented out. Feel free to either uncomment them as is or add new statements. Read the comments carefully.

    # Set a hostname. Replace machineName with your desired name.
    
    networking.hostName = "machineName";
    
    
    
    # Set the boot device.
    
    boot.loader.grub.device = "/dev/vda";
    
    
    
    # Enable SSH server.
    
    services.openssh.enable = true;
    
    
    
    # Disable SSH root login.
    
    services.openssh.permitRootLogin = "no";
    
    
    
    # Using an SSH key for authentication is STRONGLY RECOMMENDED.
    
    # Password authentication is known to be less secure and
    
    # leaves you vulnerable to brute-force attacks and drive-by
    
    # password scanning by botnets.
    
    # Comment this out to enable password authentication.
    
    # If you are using the web console thus far to configure
    
    # your VM, comment this out until after installation.
    
    services.openssh.passwordAuthentication = false;
    
    
    
    # Manage users declaratively.
    
    users.mutableUsers = false;
    
    
    
    # Add a user.
    
    users.users.nixos = {
    
      isNormalUser = true;
    
    
    
      # Set an initial password. This will be overridden.
    
      initialPassword = "ChangeMeVultr";
    
    
    
      # Add a hashed password, overrides initialPassword.
    
      # See below.
    
      # hashedPassword = "";
    
    
    
      extraGroups = [ "wheel" ];
    
      openssh.authorizedKeys.keys = [
    
        # Authorize the SSH public key from `key.pub`.
    
        # Remove this statement if you use password
    
        # authentication.
    
        (builtins.readFile ./key.pub)
    
      ];
    
    };
    

SSH Key (recommended)

A key.pub with an SSH public key should be placed within the /mnt/etc/nixos/ directory alongside configuration.nix. If you previously added your SSH key to authorized_keys, you can copy it over.

    # cp /home/nixos/.ssh/authorized_keys /mnt/etc/nixos/key.pub

Generating a Hashed Password (optional)

If you are working in the web console, skip this step until after installation. It's impossible to copy the output of mkpasswd from the Vultr console.

It's possible to store the password for the user accounts in plaintext in the configuration file with the initialPassword attribute. Still, it is strongly recommended that you store it in hashed form. This makes it easier to version control your configuration in the future, as passwords cannot be recovered from their properly hashed versions.

To generate a hashed password, run the following.

# nix-shell -p mkpasswd --run 'mkpasswd -m sha-512'

This invocation temporarily downloads the mkpasswd utility and runs a command, mkpasswd -m sha-512 in an environment with the utility in its PATH. The utility will remain available until the next garbage collection.

Uncomment the hashedPassword assignment and paste the output of mkpasswd into the string.

Add a Flake (optional)

  1. Ensure that you are still in a root shell.

    # id
    
    uid=0(root) gid=0(root) groups=0(root)
    
  2. Rerun sudo -s if this is not the case.

  3. Set up the shell environment necessary for flakes.

    # nix-shell -p nixUnstable git
    
  4. Write this file to /mnt/etc/nixos/flake.nix.

    {
    
      description = "system configuration flake";
    
    
    
      inputs = {
    
        # Replace this with any nixpkgs revision you want to use.
    
        # See a list of potential revisions at
    
        # https://github.com/NixOS/nixpkgs/branches/active
    
        nixpkgs.url = "nixpkgs/release-21.05";
    
      };
    
    
    
      outputs = inputs@{ self, nixpkgs }:
    
        let
    
          lib = nixpkgs.lib;
    
          nixConf = pkgs: {
    
            environment.systemPackages = [ pkgs.git ];
    
            nix = {
    
              package = pkgs.nixFlakes;
    
              extraOptions = ''
    
                experimental-features = nix-command flakes
    
              '';
    
              autoOptimiseStore = true;
    
              gc = {
    
                automatic = true;
    
                dates = "weekly";
    
              };
    
            };
    
          };
    
        in
    
        {
    
          # Replace machineName with your desired hostname.
    
          nixosConfigurations.machineName = nixpkgs.lib.nixosSystem rec {
    
            system = "x86_64-linux";
    
    
    
            modules = [
    
              (nixConf nixpkgs.legacyPackages.${system})
    
              ./configuration.nix
    
            ];
    
          };
    
        };
    
    }
    

Flakes require version control. Initialize a Git repository in /mnt/etc/nixos.

# cd /mnt/etc/nixos

# git init .

All files referenced by the flake must be tracked by Git.

Track all existing nix files in the directory.

git add *.nix

Run this if you added an SSH key:

git add key.pub

Install

If you elected not to use a Flake, run the following command.

nixos-install --no-root-passwd

The root password is unneeded because most operations should be run as the nixos user. Root access can be gained with sudo and the nixos user's password.

If you used a Flake, run this command instead. Be aware that if your instance is small, initial Flake installation can take a long time. It is possible at this stage to install a Channel-based system instead by running the previously given command.

nixos-install --no-root-passwd --flake /mnt/etc/nixos#machineName

As with the flake.nix customization above, replace machineName in the invocation with the hostname you chose.

If errors arise during nixos-install, the configuration.nix file can be edited to correct the errors. nixos-install can be run as many times as necessary.

Reboot and Verify

  1. Go back to the dashboard

  2. Select your server.

  3. Click the Settings tab.

  4. Find the Custom ISO sidebar in the tab.

  5. Remove the ISO. This will reboot the instance.

  6. SSH into the machine after it boots.

Set up your hashed password now if you haven't and want to. To do that, you should be able to run sudo -s to get a root shell. The password is what you set for initialPassword, such as ChangeMeVultr.

Updates

It's important to maintain systems and keep them up to date after installation. By updating, you receive patches for security issues and bugs.

All update operations should be run as root, either with sudo or in a root shell with sudo -s. This guide will assume the latter.

Flake Systems

  1. Change to /etc/nixos.

    # cd /etc/nixos
    
  2. Update pinned Nixpkgs revision

    # nix flake update
    
  3. Generate and switch to a new system from the new Nixpkgs revision. Replace machineName with your hostname.

    # nixos-rebuild switch --flake .#machineName
    

Channel Systems

  1. Change to /etc/nixos.

    # cd /etc/nixos
    
  2. Update NixOS.

    # nix-channel --update
    
  3. Generate and switch to a new system from the new Nixpkgs revision.

    # nixos-rebuild switch
    

Snapshot Your New Machine

Create a snapshot of your NixOS installation. From now on, you can deploy NixOS from a snapshot.

Want to contribute?

You could earn up to $600 by adding new articles.