Your setup machine needs the following:
Nix on your Setup Machine (unless you're using NixOS)
An id_ed25519 keypair on your Setup Machine. (Link coming soon.)
Git (Optional). Clan uses Git internally, but you can optionally install it to make your own use of it. See the Git installation instructions.
The steps in this document will erase all data on your Hetzner server's hard drive.
If you already have a server on Hetzner running, you can skip this step.
From the main Hetzner dashboard, in the left pane, click Servers.
In the upper right, click Add Server.
Choose the type; we recommend either Regular Performance or General Purpose, because these are newer.
Next, choose the row that best suits your needs; for NixOS you only need the top row, with 2 VCPUs and 2GB or 4GB RAM.
If you change the location, you might see a different set of VCPU and RAM configurations.
For Image, choose Ubuntu. (This will only be used during installation, after which NixOS will be installed.)
For Networking, select at least Public IPv4.
Under SSH keys, click Add SSH key. Leave this screen open. Open up a command shell on your local machine and type:
cat ~/.ssh/id_ed25519.pub (If you see "No such file or directory" please visit this link to learn how to create a key pair.)
Paste the contents of the id_ed25519.pub file into the SSH key box. (We recommend also checking Set as default key.) Click Add SSH key.
Scroll to the very bottom and under Name enter a name of your choice for Server name such as My-Clan-1.
In the right-hand pane, click Create && Buy now.
After a moment the server will be created.
Leave this screen open so you an copy the IP address later by clicking on the IP address.
Start by creating a new clan:
nix run "https://git.clan.lol/clan/clan-core/archive/main.tar.gz#clan-cli" --refresh -- init and enter a name for it, e.g. MY-CLAN-1, followed by a domain, e.g. myclan1.lol. (This does not have to be an actual registered domain.)
The first time you run this, Clan will automatically create an age key at ~/.config/sops/age/keys.txt. This key encrypts your secrets - back it up somewhere safe, and then type "y".
If you've run this before, you'll also be asked to select admin keys; you'll most likely want to type "1" and press enter.
Change to the new folder:
cd MY-CLAN-1 You will see a message about direnv needing approval to run. Type:
direnv allow Next, create a machine configuration, which adds a description of a machine to your inventory. For this example, call it test-machine, by typing:
clan machines create test-machine Open clan.nix, and find the inventory.machines line; add the following immediately after it; replace the IP address with your Hetzner server's IP address:
inventory.machines = { # FIND THIS LINE, ADD THE FOLLOWING
test-machine = {
deploy.targetHost = "root@<IP-ADDRESS>"; # REPLACE WITH YOUR MACHINE'S IP ADDRESS; keep "root@"
tags = [ ];
}; Test it out:
clan machines list Next, add your public key to the allowed keys. You can find it by running:
cat ~/.ssh/id_ed25519.pub Open clan.nix, and replace PASTE_YOUR_KEY_HERE with the contents of the id_ed25519.pub file:
"admin-machine-1" = "PASTE_YOUR_KEY_HERE"; Verify that your configuration is valid:
clan show Now gather the hardware configuration from the target machine:
clan machines init-hardware-config test-machine You will be asked to enter "y" to proceed.
Next, configure a disk for the target machine. You'll run this command in two steps; first, type it like so:
clan templates apply disk ext4-single-disk test-machine --set mainDisk "" This will generate an error; note the disk ID it prints out (typically starting with /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_), and add it inside the quotes, e.g.:
clan templates apply disk ext4-single-disk test-machine --set mainDisk "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_113572628" Install NixOS on the target machine by typing:
clan machines install test-machine You will be asked whether you want to install — type y. You will also be prompted for a password; you can accept the defaults and press Enter.
You will then be asked for a password to assign to the root login for the machine. You can either create one, or let Clan assign a random one.
If you get an error regarding sandboxing not being available, type the following to disable sandboxing, and then run the above command again:
clan vars generate test-machine --no-sandbox Now you can try connecting to the remote machine:
clan ssh test-machine You'll quite likely get an error at first regarding the host identification. It should include a line to type to remove the old ID; paste the line you're shown, which will look similar to this:
ssh-keygen -f '/home/user/.ssh/known_hosts' -R '<IP-ADDRESS>' Then try again:
clan ssh test-machine You should connect and see the prompt:
[root@test-machine:~]# Now let's look at how you can use Clan to install and remove packages on a target machine.
For this demonstration we'll add three command-line packages: bat, btop, and tldr. In clan.nix, under inventory.instances, add the following lines:
inventory.instances = {
packages = {
roles.default.machines."test-machine".settings = {
packages = [ "bat" "btop" "tldr" ];
};
};
# ... existing wifi service ...
}; This declares that the three packages will be present on the machine. To install them, type:
clan machines update test-machine Now ssh into the machine, and they should be present:
which bat
which btop
which tldr Each will show a path to the binary file:
/run/current-system/sw/bin/bat
/run/current-system/sw/bin/btop
/run/current-system/sw/bin/tldr Next, let's remove one of the three packages. The packages portion of clan.nix declares what additional packages should exist; by removing one, Nix will remove that package. Remove the "tldr" from the list:
packages = [ "bat" "btop" ]; and run the update again:
clan machines update test-machine Now when you check which tldr, it should show that it's not in the path:
which tldr
which: no tldr in (/run/wrappers/bin:/root/.nix-profile/bin:/nix/profile/bin:/root/.local/state/nix/profile/bin:/etc/profiles/per-user/root/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin)
When you need to add a new user, you can do so right from within the clan.nix file, and then update the system.
Let's add a user called Alice. Open clan.nix, and under inventory.instances, add the following:
inventory.instances = { # Add the following under this line
user-alice = {
module.name = "users";
roles.default.machines."test-machine" = {};
roles.default.tags.all = {};
roles.default.settings = {
user = "alice";
};
}; Save the file. Now type the following to add a password for alice (include the no-sandbox if you needed no sandbox earlier):
clan vars generate test-machine --no-sandbox You will be prompted for a password. Or you can press Enter to automatically generate one.
If you automatically generated one, to retrieve it type:
clan vars get test-machine user-password-alice/user-password On cloud machines, this password will be used for sudo access if you grant it. Typically password login is disabled on a cloud machine.
Next, let's add a key file so Alice can log in remotely. For this we'll use your own key file as before. Type:
cat ~/.ssh/id_ed25519.pub Then open machines/test-machine/configuration.nix. Add the following, before the closing brace:
{
imports = [
];
# New machine!
users.users.alice.openssh.authorizedKeys.keys = [
"PASTE_YOUR_KEY_HERE"
];
} and replace PASTE_YOUR_KEY_HERE with the contents of the file.
Now update the machine by typing:
clan machines update test-machine Once complete, you can log in as alice:
ssh alice@<IP-ADDRESS> replacing <IP-ADDRESS> with the Hetzner server's IP address.
After you trust Alice, you can grant her sudo access. To do so, update the clan.nix file by adding her to the wheel group:
user-alice = {
module.name = "users";
roles.default.machines."test-machine" = {};
roles.default.tags.all = {};
roles.default.settings = {
user = "alice";
groups = [ "wheel" ]; # Add this to allow sudo
};
}; Again type:
clan machines update test-machine If you were already logged in as alice before running the update, you will need to log out and back in for the change to take.
Then after logged in as alice, try using sudo:
sudo echo "hello" You will be prompted for the password and should see "hello" printed.
To revoke alice's sudo access, simply remove the line you added:
groups = [ "wheel" ];
And once again run:
clan machines update test-machine Log out, and log alice back in. Now try the same sudo command; you'll be prompted for password, but then shown:
alice is not in the sudoers file.