feat(services): full optional app menu + 7 more opt-in service toggles

Make the whole workstation menu available, all off/commented by default.

home.nix: the bare GUI apps become a categorized commented menu (~50
suggestions across browsers, comms, office, notes, code, graphics, A/V,
media, gaming, files/sync, security, system, local AI) — uncomment to add.

services.nix: the members that need system config (not just a package)
become opt-in nomarchy.services.* toggles, each with a commented example
in the downstream system.nix:
  - docker     → rootful Docker + user in docker group; asserts against the
                 podman docker-compat (both provide the `docker` command)
  - kdeconnect → programs.kdeconnect (opens phone-pairing ports)
  - gamemode   → Feral GameMode daemon
  - adb        → android-tools (programs.adb was removed; systemd ≥258 does
                 the device uaccess udev rules, so no group needed)
  - wireshark  → Qt GUI + user in wireshark group (capture without root)
  - ollama     → local LLM runtime on 127.0.0.1:11434
  - printing   → CUPS + Avahi/mDNS network printer discovery

README option table and ROADMAP (services item now "Fifteen shipped";
local-AI / containers / gaming / devices areas marked) updated. All seven
branches eval-verified with the toggles forced on; the docker/podman
assertion confirmed firing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-06-17 20:52:38 +01:00
parent 0c668c2eb1
commit c45fb80b79
5 changed files with 198 additions and 25 deletions

View File

@@ -227,6 +227,13 @@ examples: **[docs/OVERRIDES.md](docs/OVERRIDES.md)**.
| `nomarchy.services.steam.enable` | `false` | Opt-in: Steam via `programs.steam` (32-bit libs, controller udev, Remote-Play ports) | | `nomarchy.services.steam.enable` | `false` | Opt-in: Steam via `programs.steam` (32-bit libs, controller udev, Remote-Play ports) |
| `nomarchy.services.libvirt.enable` | `false` | Opt-in: libvirt/KVM + virt-manager GUI (login user added to `libvirtd`) | | `nomarchy.services.libvirt.enable` | `false` | Opt-in: libvirt/KVM + virt-manager GUI (login user added to `libvirtd`) |
| `nomarchy.services.obs.enable` | `false` | Opt-in: OBS Studio + a v4l2loopback virtual camera (selectable as a webcam in Zoom/Teams) | | `nomarchy.services.obs.enable` | `false` | Opt-in: OBS Studio + a v4l2loopback virtual camera (selectable as a webcam in Zoom/Teams) |
| `nomarchy.services.docker.enable` | `false` | Opt-in: rootful Docker (user in `docker` group); don't enable alongside podman |
| `nomarchy.services.kdeconnect.enable` | `false` | Opt-in: KDE Connect phone integration (opens its firewall ports) |
| `nomarchy.services.gamemode.enable` | `false` | Opt-in: Feral GameMode performance daemon (`gamemoderun`) |
| `nomarchy.services.adb.enable` | `false` | Opt-in: Android adb/fastboot tools (systemd handles device udev rules) |
| `nomarchy.services.wireshark.enable` | `false` | Opt-in: Wireshark Qt GUI (user in `wireshark` group, capture without root) |
| `nomarchy.services.ollama.enable` | `false` | Opt-in: Ollama local LLM runtime on `127.0.0.1:11434` (CPU; GPU via `services.ollama.acceleration`) |
| `nomarchy.services.printing.enable` | `false` | Opt-in: CUPS + Avahi/mDNS network printer discovery |
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

@@ -291,7 +291,7 @@ 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. **Eight shipped** in `modules/nixos/services.nix` additions trivial. **Fifteen shipped** in `modules/nixos/services.nix`
(system-side), each with a commented example in the downstream `system.nix` (system-side), each with a commented example in the downstream `system.nix`
template: `tailscale`, `syncthing` (runs as the login user, GUI on template: `tailscale`, `syncthing` (runs as the login user, GUI on
127.0.0.1:8384), `podman` (rootless, `docker` aliased, user subuid/subgid), 127.0.0.1:8384), `podman` (rootless, `docker` aliased, user subuid/subgid),
@@ -299,18 +299,25 @@ how to override it. Items marked ✓ are shipped.
`steam` (`programs.steam` — the 32-bit stack, controller udev, Remote-Play `steam` (`programs.steam` — the 32-bit stack, controller udev, Remote-Play
ports a bare package can't), `libvirt` (libvirtd + virt-manager, user added ports a bare package can't), `libvirt` (libvirtd + virt-manager, user added
to the `libvirtd` group), `obs` (OBS Studio + a v4l2loopback virtual camera to the `libvirtd` group), `obs` (OBS Studio + a v4l2loopback virtual camera
usable as a webcam in Zoom/Teams). More candidates by area: usable as a webcam in Zoom/Teams), `docker` (rootful; asserts against the
podman docker-compat), `kdeconnect`, `gamemode`, `adb` (android-tools;
systemd handles the udev rules), `wireshark` (Qt GUI + the `wireshark`
group), `ollama` (local LLM
API on 127.0.0.1:11434), and `printing` (CUPS + Avahi mDNS). More
candidates by area:
-**cloud/sync:** Syncthing (`services.syncthing`); Nextcloud client (todo) -**cloud/sync:** Syncthing (`services.syncthing`); Nextcloud client (todo)
- **local AI:** LM Studio ships as a (commented) app-suite package — a bare - **local AI:** Ollama (`nomarchy.services.ollama`, optional GPU accel)
GUI, no service config; Ollama (`services.ollama`, optional GPU accel) is ships; LM Studio is a (commented) app-suite package (a bare GUI, no
the service still todo — pairs with the menu's Ask-Claude philosophy service) — pairs with the menu's Ask-Claude philosophy
-**containers/VMs:** Podman (`virtualisation.podman`); libvirt + -**containers/VMs:** Podman (`virtualisation.podman`); libvirt +
virt-manager (`nomarchy.services.libvirt`); Docker (todo) virt-manager (`nomarchy.services.libvirt`); Docker (`nomarchy.services.docker`)
-**networking:** Tailscale (`services.tailscale`); WireGuard (todo) -**networking:** Tailscale (`services.tailscale`); WireGuard (todo)
-**gaming/media:** Steam (`nomarchy.services.steam`); OBS Studio -**gaming/media:** Steam (`nomarchy.services.steam`); OBS Studio
(`nomarchy.services.obs`, with the v4l2loopback virtual camera) (`nomarchy.services.obs`, with the v4l2loopback virtual camera); GameMode
- **devices:** printing (CUPS + Avahi); KDE Connect / phone integration; (`nomarchy.services.gamemode`)
OpenRGB -**devices:** printing (CUPS + Avahi, `nomarchy.services.printing`); KDE
Connect (`nomarchy.services.kdeconnect`); OpenRGB (todo). Plus dev tooling
— Android `adb` and `wireshark` toggles
-**backup:** Pika Backup (`pika-backup`, GUI over Borg); restic/borg -**backup:** Pika Backup (`pika-backup`, GUI over Borg); restic/borg
services (todo) services (todo)
-**escape hatch:** Flatpak (`services.flatpak`) + Flathub, for apps -**escape hatch:** Flatpak (`services.flatpak`) + Flathub, for apps

View File

@@ -45,6 +45,37 @@ in
virtual camera so an OBS scene can be selected as a webcam in Zoom, virtual camera so an OBS scene can be selected as a webcam in Zoom,
Teams or a browser (screen capture itself already works over the Teams or a browser (screen capture itself already works over the
desktop's PipeWire portal)''; desktop's PipeWire portal)'';
docker.enable = lib.mkEnableOption ''
Docker (rootful) with the login user in the `docker` group. Mutually
exclusive with the podman toggle's docker-compat (both provide the
`docker` command) enable only one'';
kdeconnect.enable = lib.mkEnableOption ''
KDE Connect for phone integration shared clipboard, notifications and
file transfer with a paired phone; opens the firewall ports it needs'';
gamemode.enable = lib.mkEnableOption ''
Feral GameMode a daemon games ask to apply a performance CPU governor
and IO/nice priorities while running (via `gamemoderun`)'';
adb.enable = lib.mkEnableOption ''
the Android platform tools (adb/fastboot) for flashing/debugging phones.
systemd 258 applies the device uaccess udev rules automatically, so the
tools alone are enough no group dance'';
wireshark.enable = lib.mkEnableOption ''
Wireshark (the Qt GUI) for packet capture, with the login user in the
`wireshark` group so capture works without root'';
ollama.enable = lib.mkEnableOption ''
Ollama, a local LLM runtime serving an API on 127.0.0.1:11434 (pair it
with the lmstudio/alpaca GUIs). CPU by default set
`services.ollama.acceleration` natively for GPU offload'';
printing.enable = lib.mkEnableOption ''
CUPS printing with Avahi/mDNS, so network printers are auto-discovered
(add vendor drivers via `services.printing.drivers`)'';
}; };
config = lib.mkMerge [ config = lib.mkMerge [
@@ -122,5 +153,56 @@ in
options v4l2loopback devices=1 video_nr=10 card_label="OBS Virtual Camera" exclusive_caps=1 options v4l2loopback devices=1 video_nr=10 card_label="OBS Virtual Camera" exclusive_caps=1
''; '';
}) })
(lib.mkIf cfg.docker.enable {
virtualisation.docker.enable = true;
users.users.${args.username}.extraGroups = [ "docker" ];
# Podman's docker-compat and real Docker both claim the `docker`
# command — guard against enabling both (unless you turn that off).
assertions = [{
assertion = !(cfg.podman.enable && config.virtualisation.podman.dockerCompat);
message = ''
nomarchy.services: docker and podman both provide the `docker`
command. Enable only one, or set
`virtualisation.podman.dockerCompat = false`.
'';
}];
})
(lib.mkIf cfg.kdeconnect.enable {
programs.kdeconnect.enable = true; # installs the app and opens its ports
})
(lib.mkIf cfg.gamemode.enable {
programs.gamemode.enable = true;
})
(lib.mkIf cfg.adb.enable {
# `programs.adb` was removed — systemd ≥258 handles the device uaccess
# udev rules, so the tools package is all that's needed now.
environment.systemPackages = [ pkgs.android-tools ];
})
(lib.mkIf cfg.wireshark.enable {
programs.wireshark = {
enable = true;
package = pkgs.wireshark; # the Qt GUI (the module defaults to the CLI)
};
users.users.${args.username}.extraGroups = [ "wireshark" ];
})
(lib.mkIf cfg.ollama.enable {
services.ollama.enable = true;
})
(lib.mkIf cfg.printing.enable {
services.printing.enable = true;
# mDNS so network printers show up without manual setup.
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
})
]; ];
} }

View File

@@ -41,10 +41,11 @@
# keybinds, theming — comes from the modules; these are the heavier # keybinds, theming — comes from the modules; these are the heavier
# standalone apps the distro doesn't impose by default. # standalone apps the distro doesn't impose by default.
# #
# Gaming (Steam) and VMs (virt-manager) are NOT here — they need system # Apps that need system setup beyond a package (Steam's 32-bit stack,
# setup beyond a package (32-bit libs, a daemon, group membership), so # a daemon, group membership, a kernel module) are NOT here — they're
# they're opt-in service toggles in system.nix instead # opt-in service toggles in system.nix instead (nomarchy.services.* —
# (nomarchy.services.steam / nomarchy.services.libvirt). # steam, libvirt, obs, docker, gamemode, kdeconnect, adb, wireshark,
# ollama, printing).
home.packages = with pkgs; [ home.packages = with pkgs; [
libreoffice-fresh # office suite (documents, sheets, slides) libreoffice-fresh # office suite (documents, sheets, slides)
vscode # code editor (unfree; allowUnfree is on) vscode # code editor (unfree; allowUnfree is on)
@@ -53,17 +54,86 @@
mpv # media player mpv # media player
amberol # music player (local library; streaming → spotify below) amberol # music player (local library; streaming → spotify below)
# ── Uncomment to add ── # ── More apps — uncomment to add ─────────────────────────────────
# firefox # a web browser (pick your own) # Web browsers
# thunderbird # email client # firefox
# signal-desktop # Signal messenger # chromium
# telegram-desktop # Telegram # ungoogled-chromium
# zoom-us # Zoom video calls (unfree) # brave # (unfree)
# teams-for-linux # Microsoft Teams (community client — no official Linux app) # google-chrome # (unfree)
# logseq # notes / outliner (PKM)
# lmstudio # local LLM runner (unfree; large closure) # Communication
# kdePackages.kdenlive # non-linear video editor (pulls in KDE libs) # signal-desktop
# spotify # music streaming (unfree) # telegram-desktop
# element-desktop # Matrix
# vesktop # Discord (themeable client)
# slack # (unfree)
# zoom-us # (unfree)
# teams-for-linux # community client (no official Linux app)
# thunderbird # email
# Office & documents
# onlyoffice-desktopeditors # stronger MS-Office fidelity
# kdePackages.okular # PDF viewer
# xournalpp # PDF annotation
# pdfarranger
# calibre # ebook library
# texliveFull # full LaTeX toolchain — multi-GB (texliveMedium is lighter) # texliveFull # full LaTeX toolchain — multi-GB (texliveMedium is lighter)
# Notes / research
# logseq
# obsidian # (unfree)
# joplin-desktop
# anki-bin # flashcards
# zotero # reference manager
# Code & data
# zed-editor
# lazygit
# dbeaver-bin # database GUI
# bruno # API client
# distrobox # containerized dev shells
# Graphics & design
# krita # digital painting
# blender # 3D
# darktable # RAW photo
# Audio / video
# audacity
# shotcut # video editor
# kdePackages.kdenlive # video editor (pulls in KDE libs)
# handbrake # transcoder
# Media
# vlc
# spotify # (unfree)
# newsflash # RSS reader
# Gaming (Steam + GameMode are service toggles in system.nix)
# lutris
# heroic # Epic/GOG launcher
# bottles # Wine prefixes
# prismlauncher # Minecraft
# protonup-qt # Proton-GE manager
# mangohud # in-game overlay
# Files, sync & torrents
# nextcloud-client
# localsend # AirDrop-like transfer
# qbittorrent
# Security
# keepassxc
# bitwarden-desktop
# System
# gnome-disk-utility
# gparted
# baobab # disk usage
# Local AI (Ollama is a service toggle in system.nix)
# lmstudio # (unfree; large closure)
# alpaca # GTK Ollama UI
]; ];
} }

View File

@@ -39,6 +39,13 @@
# nomarchy.services.steam.enable = true; # Steam (32-bit libs, controllers, ports) # nomarchy.services.steam.enable = true; # Steam (32-bit libs, controllers, ports)
# nomarchy.services.libvirt.enable = true; # libvirt/KVM + virt-manager GUI # nomarchy.services.libvirt.enable = true; # libvirt/KVM + virt-manager GUI
# nomarchy.services.obs.enable = true; # OBS Studio + v4l2loopback virtual camera # nomarchy.services.obs.enable = true; # OBS Studio + v4l2loopback virtual camera
# nomarchy.services.docker.enable = true; # Docker rootful (not alongside podman)
# nomarchy.services.kdeconnect.enable = true;# KDE Connect phone integration (opens ports)
# nomarchy.services.gamemode.enable = true; # Feral GameMode performance daemon
# nomarchy.services.adb.enable = true; # Android adb/fastboot tools
# nomarchy.services.wireshark.enable = true; # Wireshark GUI (wireshark group, no root)
# nomarchy.services.ollama.enable = true; # local LLM runtime (127.0.0.1:11434)
# nomarchy.services.printing.enable = true; # CUPS + Avahi network printer discovery
system.stateVersion = "26.05"; system.stateVersion = "26.05";
} }