9.5 KiB
nixos-systems
These are the system definitions for various systems being run by Gleipnir Technology.
Current Method
Convert to NixOS with nixos-anywhere
First log in to the host using regular credentials. Set up an ssh key for root access.
SSH key for root access
Assuming you're using a Debian base for these instructions.
$ su
# apt install sudo
# echo 'ssh-ed25519 AAA....JGTm3 me@somewhere' > ~/.ssh/authorized_keys
# chmod 600 ~/.ssh/authorized_keys
Now log out and see if you can SSH into the host as root. nixos-anywhere will be using SSH as root quite a bit.
Copy a baseline config
Start by copying an existing host config to a new subdirectory. For me right now I'm working on an AMD Legacy Quadrcore, so I"ll copy one of those:
cp host/nocix/amd-legacy-quadcore host/nocix/amd-legacy-quadcore-123456
You'll then need to update flake.nix to have an entry for the new host configuration.
Configure root disk
Get the disk layout using /sbin/fdisk -l. You're looking to figure out which disk is the boot disk and which isn't. Use ls -l /dev/disk/by-id/ to figure out the ID, which should be stable across reboots. Then update the host/nocix/amd-legacy-quadcore-123456/disk-config.nix file for the matching provider to ensure that the boot disk gets written.
Configure network
Then check the network configuration via ip route and ip addr or /etc/network/interfaces. Update the network configuration at host/nocix/amd-legacy-quadcore-123456/network.nix to match.
Generate the hardware configuration
Generate the hardware configuration
$ cd nixos-anywhere
$ nix run github:nix-community/nixos-anywhere -- --flake ./#nocix --generate-hardware-config nixos-generate-config ./nocix/hardware-configuration.nix --target-host root@1.2.3.4
This apparently destroys the operating system. I'm not sure why.
The important thing is that it'll generate the hardware configuration at ./nocix/hardware-configuration.nix which is different for every host and based on the specific CPU architecture and features.
You'll have to reload the operating system after this. Sorry. Then restart by adding the SSH config with the new password generated when the OS is reloaded.
At this point you can then actually deploy the NixOS anywhere with:
$ cd nixos-anywhere
$ nix run github:nix-community/nixos-anywhere -- --flake ./#nocix --target-host root@1.2.3.4
This will take a while, maybe 10 minutes, and disconnect and reboot the server. From there you can ping it and wait for it to come back, usually around 10 minutes again. I think. I don't watch it.
Deploy full system
At this point you've got a server that has NixOS on it, but it's just a bare system missing most of its purpose. That's because we used nixos-anywhere and a special flake instead of our regular flakes.
You can start with copyng files from a working host
$ cp -R host/nocix/amd-legacy-quadcore-123 host/nocix/amd-legacy-quadcore-456
Then copy over the configuration files created during the nixos-anywhere steps above
$ cp nixos-anywhere/nocix/hardware-configuranion.nix nixos-anywhere/nocix/network.nix host/nocix/amd-legacy-quadcore-456
Before this will work you need to commit the files created in the above steps - nix flakes ignore files on disk that aren't in source code management if you're operating in a git repo context.
This may take a while, maybe 20 minutes, but after you'll have a fully-functioning NixOS system with the correct SSH keys.
Adding a new host to the secrets
The host should create its own new ssh host key that lives at /etc/ssh/ssh_host_ed25519_key.pub. We're going to convert that into a sops key and add it to our key material.
On the server you just added run:
$ nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'
age1lzzlx60f9ra4evdkn4l9px735mz7uxml5467ptzc4hg3t86gn9mq3ddsxy
This will produce an age key. Copy that into .sops.yaml. You'll want to add it to the list of keys at the top, then add it to any sections that the host should be able to read. Once that's done you'll need to add the key into each secret file's encryption with the following on a dev machine:
$ nix-shell -p sops --run "sops updatekeys secrets/example.yaml"
See the official sops-nix docs for details.
Switch-fix
I've added a tool, switch-fix to the deployment. From the docs:
"you set-rollback before you do your nixos-rebuild switch."
"you do cancel-rollback if it works"
"you wait if it doesn't, and the system should come back."
Successful avenues of exploration
nixos-anywhere
See failed section for stuff before this
Eventually got around to building a s-2vcpu-4gb system:
$ nix run github:nix-community/nixos-anywhere -- --flake ./nixos-anywhere/flake.nix#digitalocean --target-host root@128.199.4.31
This worked and I was then able to ssh in as root. Interestingly, it has no /etc/nixos/* files (but the directory does exist). Resulting disk images:
# fdisk -l
Disk /dev/vda: 80 GiB, 85899345920 bytes, 167772160 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: E0C9241B-89EA-4E2C-A0CD-04A3FDEFEDA2
Device Start End Sectors Size Type
/dev/vda1 2048 4095 2048 1M BIOS boot
/dev/vda2 4096 1028095 1024000 500M EFI System
/dev/vda3 1028096 167770111 166742016 79.5G Linux filesystem
Disk /dev/vdb: 482 KiB, 493568 bytes, 964 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/pool-root: 79.51 GiB, 85370863616 bytes, 166739968 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Next we'll try something at half that size
s-1vcpu-2gb works fine. We won't bother going smaller at this point.
Failed Avenues of Exploration
These are things that I wanted to have work, but just didn't in the way I had hoped.
Custom System Image
The idea here is to use NixOS to create a custom system image, upload it, and then start servers based on that image. It actually works really well, except that Digital Ocean categorically does not support IPv6 networking on custom images. That's bollocks.
Hat tip to the negation for some ideas here.
Build a custom image for Digital Ocean:
> nix-build digitalocean/custom-image.nix
...
/nix/store/rm84j1a5bskhg2z8gz633m4apjyg848c-digital-ocean-image
> ls -lh result/
nixos-image-digital-ocean-25.05pre-git-x86_64-linux.qcow2.gz nix-support/
In order to "upload" the image to Digital Ocean you'll need to make the image available via URL. We can use Gleipnir static storage as an example:
rsync result/nixos-image-digital-ocean-25.05pre-git-x86_64-linux.qcow2.gz static.gleipnir.technology:/tmp
Make sure the image is accessible via a public URL. Then upload either through the web interface, or using doctl
> doctl compute image create "Gleipnir NixOS 25.05" -v --image-description "NixOS 25.05 with ssh keys for eliribble baked in" --image-distribution nixos-25.05 --image-url "https://static.gleipnir.technology/nixos-image-digital-ocean-25.05pre-git-x86_64-linux.qcow2.gz" --region sfo3 --tag-names nixos
ID Name Type Distribution Slug Public Min Disk Created
192948683 Gleipnir NixOS 25.05 custom Unknown OS false 0 2025-07-10T20:22:43Z1G
Then start a droplet using that image:
> doctl compute droplet create "test2.nidus.cloud" --enable-ipv6 --image 192948683 --project-id ce2159e8-02f5-4169-8943-f34ccf812d23 --region sfo3 --size s-1vcpu-1gb --ssh-keys 48777034 --tag-name nixos --wait
Error: POST https://api.digitalocean.com/v2/droplets: 422 (request "116c778d-8e72-4099-a7c6-c3ad37557c4c") image is not compatible with ipv6
Oh. Well that sucks. Digital Ocean can't do IPv6 on custom images.
NixOS Infect via cloud-init
The idea here is to spawn a stock Debian system from Digital Ocean's supported image, then immediately infect it on boot to become a real NixOS system, but with proper IPv6 networking
I tried creating a cloud-init function based on NixOS-infect. You can see the content in digitalocean/infect-nixos.yaml. I added it to the startup command via doctl compute droplet create ... --user-data-file digitalocean/infect-nixos.yaml. This may have a way of working, but I don't get a log and it doesn't get infected, so something fundamental isn't working. I abandoned it.
Nixos-anywhere Investigation
First we start up a really small s-1vcpu-1gb. Then we try to install nixos via nixos-anywhere. Notice the --no-disko-deps which is recommended for very low RAM systems:
$ nix run github:nix-community/nixos-anywhere -- --no-disko-deps --flake ./nixos-anywhere#digitalocean --target-host root@64.23.242.187
After an hour it was railed on the CPU at 100% and had been for an hour with no network data going anywhere. I gave up. Must be too small. Tried again with a larger system, s-2vcpu-4gb:
See successful investigations for what happened after that.