feat(services): opt-in Tailscale + Syncthing (nomarchy.services.*)

Start the opt-in services surface: nomarchy.services.{tailscale,syncthing},
off by default, in modules/nixos/services.nix. Tailscale ships the daemon
(authenticate with `sudo tailscale up`); Syncthing runs as the login user
with its GUI on 127.0.0.1:8384 (overrideDevices/Folders off so GUI-managed
folders survive rebuilds). username is read lazily, only when Syncthing is
on. Commented examples in the downstream system.nix template per the opt-in
convention.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-06-16 17:08:41 +01:00
parent 8d3911de1a
commit fb748c217c
5 changed files with 58 additions and 8 deletions

View File

@@ -219,6 +219,8 @@ examples: **[docs/OVERRIDES.md](docs/OVERRIDES.md)**.
| `nomarchy.system.power.laptop` | `false` | Marks a laptop, gating battery-only features; the installer sets it when a battery is present | | `nomarchy.system.power.laptop` | `false` | Marks a laptop, gating battery-only features; the installer sets it when a battery is present |
| `nomarchy.system.power.thermal.enable` | `false` | thermald (Intel-only); the installer enables it on a GenuineIntel CPU | | `nomarchy.system.power.thermal.enable` | `false` | thermald (Intel-only); the installer enables it on a GenuineIntel CPU |
| `nomarchy.system.power.batteryChargeLimit` | `null` | Stop charging at this % (e.g. `80`) where the hardware supports it; needs `power.laptop` | | `nomarchy.system.power.batteryChargeLimit` | `null` | Stop charging at this % (e.g. `80`) where the hardware supports it; needs `power.laptop` |
| `nomarchy.services.tailscale.enable` | `false` | Opt-in: Tailscale mesh VPN (then `sudo tailscale up`) |
| `nomarchy.services.syncthing.enable` | `false` | Opt-in: Syncthing file sync as the login user (GUI at `127.0.0.1:8384`) |
Beyond the `nomarchy.*` surface, the system layer turns on the usual Beyond the `nomarchy.*` surface, the system layer turns on the usual
desktop services with `lib.mkDefault` (override natively). One worth desktop services with `lib.mkDefault` (override natively). One worth

View File

@@ -261,22 +261,27 @@ how to override it. Items marked ✓ are shipped.
application suite above — heavier or more personal integrations shipped application suite above — heavier or more personal integrations shipped
**off by default**, each a `nomarchy.services.<name>.enable` toggle a **off by default**, each a `nomarchy.services.<name>.enable` toggle a
downstream flips on in one line. Keeps the base lean while making common downstream flips on in one line. Keeps the base lean while making common
additions trivial. Candidates by area: additions trivial. **✓ First two shipped** — `nomarchy.services.tailscale`
- **cloud/sync:** Nextcloud client; Syncthing (`services.syncthing`) and `nomarchy.services.syncthing` (`modules/nixos/services.nix`, system-side;
Syncthing runs as the login user with its GUI on 127.0.0.1:8384), with
commented examples in the downstream `system.nix` template. More candidates
by area:
-**cloud/sync:** Syncthing (`services.syncthing`); Nextcloud client (todo)
- **local AI:** LM Studio (`lmstudio`); Ollama (`services.ollama`, optional - **local AI:** LM Studio (`lmstudio`); Ollama (`services.ollama`, optional
GPU accel) — pairs with the menu's Ask-Claude philosophy GPU accel) — pairs with the menu's Ask-Claude philosophy
- **containers/VMs:** Docker/Podman; libvirt + virt-manager - **containers/VMs:** Docker/Podman; libvirt + virt-manager
- **networking:** Tailscale (`services.tailscale`); WireGuard - **networking:** Tailscale (`services.tailscale`); WireGuard (todo)
- **gaming/media:** Steam (`programs.steam`); OBS Studio - **gaming/media:** Steam (`programs.steam`); OBS Studio
- **devices:** printing (CUPS + Avahi); KDE Connect / phone integration; - **devices:** printing (CUPS + Avahi); KDE Connect / phone integration;
OpenRGB OpenRGB
- **backup:** restic/borg (`services.restic`) - **backup:** restic/borg (`services.restic`)
- **escape hatch:** Flatpak (`services.flatpak`) for apps outside nixpkgs - **escape hatch:** Flatpak (`services.flatpak`) for apps outside nixpkgs
Decisions: the curated set; whether system services and GUI apps share one Surface decided: `nomarchy.services.*`, system-side for system services
surface or split (`nomarchy.services.*` system-side vs home-side packages); (home-side ones can extend the same prefix later). Remaining: curate the
and how it relates to `nomarchy.apps.*` (opt-out suite). Unfree entries are rest (Ollama, containers, Steam/OBS, printing, backups, Flatpak …) and
already covered (`allowUnfree = true`). decide how it relates to `nomarchy.apps.*` (opt-out suite). Unfree entries
are already covered (`allowUnfree = true`).
-**Display / monitor management:** declarative `nomarchy.monitors` (a -**Display / monitor management:** declarative `nomarchy.monitors` (a
per-output schema — name/resolution/position/scale/transform/mirror/ per-output schema — name/resolution/position/scale/transform/mirror/
bitdepth/vrr/disable) generates Hyprland `monitor` rules, keeping the bitdepth/vrr/disable) generates Hyprland `monitor` rules, keeping the

View File

@@ -22,7 +22,7 @@ let
''; '';
in in
{ {
imports = [ ./options.nix ./plymouth.nix ./file-manager.nix ./power.nix ]; imports = [ ./options.nix ./plymouth.nix ./file-manager.nix ./power.nix ./services.nix ];
config = { config = {
# The safe half of distro branding: distroName flows into # The safe half of distro branding: distroName flows into

View File

@@ -0,0 +1,40 @@
# Opt-in services & integrations — off by default, one toggle each, enabled
# in system.nix (see the commented examples in the downstream template).
# These are system services: Tailscale is system-only, and Syncthing runs as
# the login user. Their own `nomarchy.services.*` namespace, distinct from the
# distro's core `nomarchy.system.*` toggles. `username` (from specialArgs) is
# read lazily, only when Syncthing is enabled.
{ config, lib, ... }@args:
let
cfg = config.nomarchy.services;
in
{
options.nomarchy.services = {
tailscale.enable = lib.mkEnableOption ''
Tailscale, the mesh VPN ships the daemon; authenticate once with
`sudo tailscale up`'';
syncthing.enable = lib.mkEnableOption ''
Syncthing continuous file sync, running as the login user add
folders and devices in the web UI at http://127.0.0.1:8384'';
};
config = lib.mkMerge [
(lib.mkIf cfg.tailscale.enable {
services.tailscale.enable = true;
})
(lib.mkIf cfg.syncthing.enable {
services.syncthing = {
enable = true;
user = args.username;
# Manage folders/devices in the GUI; don't let the (empty) declarative
# config wipe them on a rebuild.
overrideDevices = false;
overrideFolders = false;
guiAddress = "127.0.0.1:8384";
};
})
];
}

View File

@@ -30,6 +30,9 @@
# batteryChargeLimit = 80; # cap charging for longevity # batteryChargeLimit = 80; # cap charging for longevity
# thermal.enable = true; # thermald (Intel CPUs) # thermal.enable = true; # thermald (Intel CPUs)
# }; # };
#
# nomarchy.services.tailscale.enable = true; # mesh VPN — then `sudo tailscale up`
# nomarchy.services.syncthing.enable = true; # file sync — GUI at http://127.0.0.1:8384
system.stateVersion = "26.05"; system.stateVersion = "26.05";
} }