# NixOS on Hetzner Cloud

> Source: <https://gist.github.com/cyber-murmel/8b726b45047907a842a9dc9db2618b0a>
> Published: 2022-02-06 01:30:58+00:00

This is the gist of how to setup a [NixOS](https://nixos.org/) server on a [Hetzner Cloud](https://www.hetzner.com/cloud) instance with an `admin` user, ssh access and configuration management via git.

1. Create a Hetzner Cloud instance and click to enter it.
2. Stop the instance (top right corner icon).
3. Go to *ISO Images*.
4. Search for "nixos" and click *mount*.
![ISO Images tab of a Hetzner Cloud instance with the NixOS image already mounted](https://user-images.githubusercontent.com/30078229/152664634-d580278d-5dd2-468f-b113-f2581d69a5b1.png)
5. Start the instance again (top right corner icon).
6. Open the console (top right corner icon).
7. Get the IP address by executing `ip --brief --color address`. The address can also be optained from the Hetzner Cloud web interface.
```
lo               UNKNOWN        127.0.0.1/8 ::1/128
enp61s0          UP             <IPv4 address>/24 <IPv6 address>/64
```
8. Download your public ssh key to the machine. If you have a GitHub account you can download it from there.
```bash
mkdir ~/.ssh
curl -L https://github.com/<username>.keys | tee -a .ssh/authorized_keys
```
9. Log on from your computer on via ssh.
```bash
ssh nixos@<IPv4 address>
```
10. Partition, format and mountthe disk.
```bash
sudo -i
# Create a GPT partition table.
parted /dev/sda -- mklabel msdos
# Add the root partition.
parted /dev/sda -- mkpart primary 1MiB 100%
partprobe
# Format the partition.
mkfs.ext4 -L nixos /dev/sda1
# Mount root.
mount /dev/disk/by-label/nixos /mnt
```
11. Generate the initial configuration and install.
```bash
nixos-generate-config --root /mnt
# Set boot device.
sed -e 's/^.*boot\.loader\.grub\.device.*$/  boot.loader.grub.device = "\/dev\/sda";/g' -i /mnt/etc/nixos/configuration.nix
# Create a directory to manage configurations and import it in the generated config.
mkdir /mnt/etc/nixos/configuration/
sed -e 's/\.\/hardware-configuration\.nix/.\/hardware-configuration.nix\n      .\/configuration/g' -i /mnt/etc/nixos/configuration.nix
```
12. Open `/mnt/etc/nixos/configuration/default.nix` with an editor like `vim` or `nano` and paste the following.
```nix
{ config, pkgs, ... }:

{
  imports =
    [
      ./user.nix
    ];
  environment.systemPackages = with pkgs; [
    vim
    wget
    git
    htop bottom
  ];
  services.openssh.enable = true;
}
```
13. Open `/mnt/etc/nixos/configuration/user.nix` with an editor and paste the following to create an account with the name *admin*. **Replace the public ssh key with yours**.
```nix
{ config, pkgs, ... }:

{
  imports = [
  ];
  users = {
    users = {
      admin = {
        isNormalUser = true;
        extraGroups = [ "wheel" ];
        initialHashedPassword = "";
        openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA...." ];
      };
    };
  };
}
```
15. Perform installation.
```bash
nixos-install --no-root-passwd
```
16. Enter the mounted installation and set a password for the admin account.
```bash
nixos-enter --root /mnt
passwd admin
exit
```
17. Shut down the machine.
```bash
poweroff
```
18. Unmount the ISO in the Hetzner Cloud interface and start the machine again.
19. Log on via SSH.
```bash
# Remove old host key from install system.
ssh-keygen -R <IPv4 address>
# Log in as admin
ssh admin@<IPv4 address>
```
20. Turn custom config into repo of admin for convenience
```bash
mkdir repos
cp -R /etc/nixos/configuration/ repos/
cd repos/configuration/
# Initialize repository with placeholder configuration.
git init
git config user.name admin
git config user.email admin@localhost
git add .
git commit -m "initial commit"
# Remove replace old files with symbolic link.
sudo rm -r /etc/nixos/configuration/
sudo ln -s /home/admin/repos/configuration/ /etc/nixos/
# Test by rebuilding system
sudo nixos-rebuild dry-run
```
21. Have fun and happy hacking!
