Setting up a NixOS server in UpCloud
How to set up a NixOS server in UpCloud
This is not about Nix, but more of a tutorial on how I set up a server using UpCloud. I decided to document the steps I took to create a NixOS playground for myself.
Requirements
- UpCloud account
- SSH keys for secure access
- At least some Linux experience
Why UpCloud
Honestly, I just checked European Alternatives and chose UpCloud, because it’s Finnish.
I was surprised that there were a few cheap server options; I had expected to pay more. Then again, it seems like UpCloud is bigger than I had thought.
I’m running this on the smallest developer server, which has 1 CPU, 1 GB RAM and 10 GB storage, and costs 3 euros per month.
Support
I contacted support twice during the initial setup and was positively surprised how fast they responded (even on a saturday) and how good the advice was.
Getting started
When creating a new server, there is an option to select from a set of preloaded CD/ROM images which happens to include NixOS 24.11 Minimal Installation CD and NixOS 25.05 Minimal Installation CD.
I chose 25.05 because why not. I used the NixOS Manual as a guide.
I didn’t have to worry about networking, it was working out-of-the-box.
Hitting a surprising wall
After deploying the server I logged in using the console provided by UpCloud, sudoed up (sudo -i), and this is where my problems started.
There was no / on the keyboard layout. I tried every key that I could think of.
I’m still not quite sure what the actual issue here is, would be interesting to know.
Solving the keys
After trying different loadkeys commands, trying to set xserver layout, googling for an answer and trying everything that ChatGPT could come up with
I was getting a bit frustrated.
# This did work, but the problem wasn't actually the keymap itself
loadkeys us
# This actually had `/`, but didn't have `-` so no luck there either when a command required both of those
loadkeys fi
localectl list-keymaps
Failed to read list of keymaps: No such file or directory
I had some help from a friend, who explained a bit how keymaps work and how they can be created.
With that small nudge in the right direction the solution was extremely simple: just create a minimal keymap, which adds the necessary keys.
By running the showkey command I could see which keys I needed to remap.
For me SHIFT + 7 showed keycode 53, so I just had to add a new mapping for that.
Note: This does not persist between reboots and the installation environment does not persist files.
vi custom.map
keycode 53 = slash slash
loadkeys custom.map
Partitioning
I could not find out how UpCloud expects me to partition the system, so initially I tried with UEFI.
This ended with facing Booting from Hard Disk... multiple times after making changes to the config, changing the boot media and trying again.
I reached out to support and they explained that UpCloud uses BIOS for booting. The immediate next boot was a success.
# Partitioning
# wipe disk and create MBR
parted /dev/vda -- mklabel msdos
# swap partition: 1 GiB
parted /dev/vda -- mkpart primary linux-swap 1MiB 1025MiB
# root partition: rest of the disk
parted /dev/vda -- mkpart primary ext4 1025MiB 100%
# Formatting
# swap
mkswap /dev/vda1
swapon /dev/vda1
# root
mkfs.ext4 /dev/vda2
mount /dev/vda2 /mnt
Initial config
I generated the initial config using nixos-generate-config --root /mnt.
On my first setup I rebooted after setting only the boot config because I just wanted to see if it works,
but the minimal NixOS doesn’t include vi so I would rather do the setup before booting to the actual system.
I actually had to use nano and because I didn’t have access to {}; on the layout
I had to copy paste the symbols while writing the config.
cd /mnt/etc/nixos
vi configuration.nix
# Boot loader
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/vda";
# Neovim
programs.neovim.enable = true;
# User config
# I didn't want to log in using the root, so I created a new user
# by uncommenting and editing the existing one
users.users.mituuz = {
isNormalUser = true;
extraGroups = [ "wheel" ];
packages = with pkgs; [
tree
];
};
# SSH config
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = true;
PermitRootLogin = "no";
};
};
Then running nixos-install does the magic and sets up the system.
If the installation is successful, NixOS asks you to set a password for the root user.
You can shutdown the system after that: shutdown -h now.
First boot
Then from the UpCloud server Overview - Optionals you can change the boot order to boot from storage instead of cdrom.
Restarting the server should launch us into the actual system. Log in as root and set a password for your user passwd mituuz.
Then we should be able to use SSH to log in and not have to worry about strange layouts.
Securing SSH config
First things first, I wanted to disable password login and add an SSH key to the server.
sudo nvim /etc/nixos/configuration.nix
# Add the ssh key to the user config
users.users.mituuz = {
isNormalUser = true;
extraGroups = [ "wheel" ];
packages = with pkgs; [
tree
];
openssh.authorizedKeys.keys = [ "pubkey goes here" ];
};
# Disable password login
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
Then we can rebuild the system in place sudo nixos-rebuild switch and we’re done.
Conclusion
Now we have a pretty minimal NixOS running on UpCloud with SSH keys configured and ready to dive in.
Time to see if NixOS lives up to the hype. My initial impression is positive. I like the declarative configurations and not having to commit to any packages or dependencies. Only having to install what is absolutely necessary sounds nice.
I’m just testing for now, but at the same time I’m feeling out if I would like to replace my home server with NixOS later.