- Nix 95.3%
- Python 4.7%
| hosts | ||
| modules | ||
| pkgs | ||
| profiles | ||
| secrets | ||
| users | ||
| .gitignore | ||
| .sops.yaml | ||
| flake-imports.nix | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
nix-lab
Isolated lab environment: a nix-darwin managed MacBook driving NixOS VMs
(nextcloud-core, nextcloud-media).
Layout: flake-parts + import-tree, so new .nix files under modules/, profiles/ and users/ are
picked up automatically. Hosts live in hosts/<name>/ and are registered in flake.nix.
Users follow the <username> pattern: users/admin.nix declares the read-only
myConfig.primaryUser option (= admin) plus the account for the VMs;
users/changeme.nix does the same for the Mac's user, with
users/changeme-packages.nix adding programs/packages on top. Every
other module reads config.myConfig.primaryUser instead of hardcoding a name.
Bootstrap (Mac)
- Clone this repo to
~/nix-lab(the path the fish functions expect; override via themyFlakePathhome option if you pick another location).
git clone https://git.kiwerte.de/Ainfacher/nix-nextcloud-stack.git ~/nix-lab
-
Rename
users/changeme.nixaccording to the macOS short username and replace all placeholders (changeme) inhosts/macbook/default.nixetc. If Nix was installed with the Determinate installer — uncommentnix.enable = false). -
First rebuild:
sudo nix --extra-experimental-features "nix-command flakes" run github:nix-darwin/nix-darwin/nix-darwin-26.05#darwin-rebuild -- switch --flake /Users/changeme/nix-lab#macbook
Afterwards the fish function rebuild-mac switch (= sudo darwin-rebuild switch --flake ~/nix-lab#macbook) does the same.
- You can make fish the login shell (it is in
/etc/shellsafter step 3):
chsh -s /run/current-system/sw/bin/fish
or just drop into fish from your normal terminal with
fish
- Generate the lab SSH key and paste its public half into
users/admin.nix(openssh.authorizedKeys.keys) — it authorizes SSH asadminon the VMs:
ssh-keygen -t ed25519
You can also use an existing ssh key/identity. Just make sure, if whatever key you want to use
differs from ~/.ssh/id_ed25519, change the entry in modules/managed-hosts.nix for identityFiles (right at the top).
- Generate the Mac's age key and register it in
.sops.yaml:
mkdir -p "$HOME/Library/Application Support/sops/age"
age-keygen -o "$HOME/Library/Application Support/sops/age/keys.txt"
- Through the hypervisor add the following lines to
/etc/nixos/configuration.nix:
services.openssh.enable = true;
nix.settings.experimental-features = ["nix-command"];
swapDevices = [
{
device = "/var/lib/swapfile";
size = 16 * 1024;
}
];
and add the following package to environment.systempackages
kitty.terminfo
- After building a new gen with
sudo nixos-rebuild switch
convert its host key and add it to .sops.yaml using:
ssh admin@IP.addr.of.vm "cat /etc/ssh/ssh_host_ed25519_key.pub" | ssh-to-age
- Fill all necessary secrets in
secrets/nextcloud.yamland encrypt it inplace using:
sops --encrypt --in-place secrets/nextcloud.yaml
- Copy over the hardware-configuration.nix file contents with:
ssh admin@IP.addr.of.vm "cat /etc/nixos/hardware-configuration.nix"
-
Check the configured network settings inside
nix-lab/modules/network-defaults.nix. -
Generate a password hash for the
adminaccount (or whatever you named it) with:
printf "<actual pw>" | mkpasswd -m sha-512 -s
Create a nix-lab/secrets/admin.yaml file with (you need to be inside the nix-lab folder):
sops secrets/admin.yaml
The entry should be:
admin-password: <the hash>
- Deploy the nextcloud configs from the Mac:
nixos-rebuild-ng boot --flake ~/nix-lab#nextcloud-core --target-host admin@X.X.X.X --build-host admin@X.X.X.X --sudo --use-substitutes --ask-sudo-password
After that build successfully, reboot the VM. Further rebuilds can be done via rebuild-nextcloud-core boot/switch.
Additional Info
The Mac only evaluates; the VM builds its own generation (--build-host
defaults to the target). When a dedicated build server exists, set
buildHost = "<its-alias>" in users/changeme-hosts.nix or configure it in nix-settings.nix.
Adding a host: create hosts/<name>/ (importing admin, base,
server-vm), register it in flake.nix (nixosConfigurations), add an
entry to myHosts in users/changeme-hosts.nix — SSH alias, login user
and rebuild-<name> function are generated from the host's own config.
Ports
Nextcloud-Core
| Proto | Port | Why |
|---|---|---|
| TCP | 443 | The single entry point for all HTTPS: nc., office., n8n. (terminated locally) and talk. (SNI-routed raw to nc-media). Mandatory. |
| TCP | 80 | Plain-HTTP vhost that redirects to 443. Not required for function in manual mode (no ACME challenges), but forward it so http:// links redirect properly. Recommended. |
Nextcloud-Media
| Proto | Port(s) | Why |
|---|---|---|
| UDP | 3478 | Plain STUN/TURN — primary path for WebRTC NAT traversal (turn:...:3478?transport=udp). |
| TCP | 3478 | TURN over TCP fallback for clients on UDP-blocking networks (turn:...:3478?transport=tcp). |
| TCP | 5349 | TURN over TLS — turns:...:5349?transport=tcp, advertised when NOT in proxy mode. |
| UDP | 49152–49407 | coturn relay range. When peers can't connect P2P, their audio/video is relayed through coturn on these ports; they must be externally reachable or relayed calls have no media. |
Updating
On the Mac run update-nix in a fish terminal. This executes nix flake update with the correct flag, updating the available packages for all hosts. It also commits this change automatically to the git repo (can be configured/changed in the nix-lab/modules/fish.nix file).
After that build a new Nix(OS)-Generation for either the Mac (rebuild-mac switch) or the Nextcloud hosts (e.g. rebuild-nextcloud-core boot).
switch builds and loads the new, updated generation immediately. boot builds the new, updated generation and adds it to the bootloader, making it the default generation on the next boot of the host, therefore requiring a reboot to activate it.
Formatting
nix fmt