diff --git a/home/server.nix b/home/server.nix index 0e030f9..4d9f4cc 100644 --- a/home/server.nix +++ b/home/server.nix @@ -7,35 +7,12 @@ { home.stateVersion = "25.11"; - # User-level tools installed outside Nix (PinchTab, pi wrapper, etc.). + # User-level tools installed outside Nix (pi wrapper, etc.). home.sessionPath = [ "${config.home.homeDirectory}/.local/bin" "${config.home.homeDirectory}/.local/libexec" ]; - # Keep the browser control plane alive across SSH logout and reboots. - # PinchTab itself is installed outside Nix because its upstream release - # binary is dynamically linked; the local NixOS-compatible build lives in - # ~/.local/libexec/pinchtab. - systemd.user.services.pinchtab = { - Unit = { - Description = "PinchTab browser control plane"; - After = [ "dbus-broker.service" ]; - }; - Service = { - ExecStart = "%h/.local/libexec/pinchtab server"; - Restart = "on-failure"; - RestartSec = 5; - Environment = [ - "HOME=%h" - "PATH=/run/current-system/sw/bin:/home/mikl/.npm-global/bin:/home/mikl/.local/bin:/home/mikl/.local/libexec" - ]; - }; - Install = { - WantedBy = [ "default.target" ]; - }; - }; - home.file.".local/bin/pi" = { executable = true; text = '' @@ -61,6 +38,9 @@ # Редактор vim + # Node.js runtime for the user-installed pi CLI and extensions + nodejs + # Git git tea # Forgejo/Gitea CLI diff --git a/hosts/heather/arion-compose.nix b/hosts/heather/arion-compose.nix index b52cc5e..fd12d9b 100644 --- a/hosts/heather/arion-compose.nix +++ b/hosts/heather/arion-compose.nix @@ -172,7 +172,7 @@ in # /var/lib/tuwunel-secrets/tuwunel.toml (root:docker 0640, bind-mount ro) # Cinny config: /var/lib/tuwunel-secrets/cinny-config.json (bind-mount ro). tuwunel = { - service.image = "ghcr.io/matrix-construct/tuwunel:v1.7.1"; + service.image = "ghcr.io/matrix-construct/tuwunel:v1.9.3"; service.container_name = "tuwunel"; service.restart = "unless-stopped"; service.volumes = [ @@ -231,6 +231,12 @@ in service.image = "teableio/teable@sha256:04c0c041c79564de7c06fc005d5560f9553161557a776caf1ed36c9c38ea8600"; service.container_name = "teable"; service.restart = "unless-stopped"; + # Teable previously had no cgroup limit and helped trigger the host-wide + # OOM on 2026-09-24. Keep its startup/runtime spike from taking down + # SSH, Caddy, and the rest of the server. + # Arion 0.2.2 does not expose mem_limit as a typed option; use its + # raw output escape hatch so docker-compose gets the cgroup limit. + out.service.mem_limit = "2g"; service.ports = [ "127.0.0.1:2345:3000" ]; service.volumes = [ "teable-data:/app/.local-storage" diff --git a/hosts/heather/caddy.nix b/hosts/heather/caddy.nix index 28104de..d3d1b4b 100644 --- a/hosts/heather/caddy.nix +++ b/hosts/heather/caddy.nix @@ -119,6 +119,11 @@ Allow: /" 200 reverse_proxy 127.0.0.1:8890 ''; + # Nick timer prototype. Public timer pages; creation has no auth for now. + "timer.michaotic.space".extraConfig = '' + reverse_proxy 127.0.0.1:8787 + ''; + # File explorer (directory listing) для раздачи файлов через браузер. # browse включает Caddy's built-in directory listing. Корень /var/www/pub. # Без auth — класть только публичные файлы. diff --git a/hosts/heather/default.nix b/hosts/heather/default.nix index caad7c1..2d3851a 100644 --- a/hosts/heather/default.nix +++ b/hosts/heather/default.nix @@ -21,17 +21,31 @@ ./syncthing.nix # sync + relay ./tuwunel-admin.nix # matrix admin web UI (systemd, статический бинарник) ./paseo.nix # paseo daemon (web UI для CLI-агентов, systemd + npm global) + ./nick.nix # Nick timer prototype (systemd, localhost:8787) ./jupyter.nix # JupyterLab (systemd, localhost:8890, лимиты) ./mesh-clients.nix # Sol-style client pool (wg-clients1) ./mesh-egress.nix # Sol-style selected-destination egress policy ]; + # Heather has 8 GiB RAM and runs several containers. Keep a 4 GiB + # swapfile so a transient application spike does not take down the host. + swapDevices = [ + { + device = "/var/swapfile"; + size = 4096; + } + ]; + # First server-to-server WireGuard backbone link: heather ↔ hyacinth. # The private key is generated on the live host and stays outside the flake. - # Chromium для PinchTab: отдельный headless-браузер для agent automation. - environment.systemPackages = [ - pkgs.wireguard-tools - pkgs.chromium + # Basic diagnostics/admin tools must be available even in non-login SSH + # sessions (and not depend on a stale Home Manager profile). + environment.systemPackages = with pkgs; [ + wireguard-tools + tmux + jq + wget + python3 ]; # NixOS uses scripted networking here (not systemd-networkd), so create the diff --git a/hosts/heather/nick.nix b/hosts/heather/nick.nix new file mode 100644 index 0000000..8427012 --- /dev/null +++ b/hosts/heather/nick.nix @@ -0,0 +1,31 @@ +# Nick timer prototype. +# Source is deployed separately to /home/mikl/sideprojects/other/nick. +# Caddy terminates TLS; the app only listens on localhost. + +{ config, pkgs, lib, ... }: +{ + systemd.services.nick-timer = { + description = "Nick timer prototype"; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "simple"; + User = "mikl"; + Group = "users"; + WorkingDirectory = "/home/mikl/sideprojects/other/nick"; + ExecStart = "/home/mikl/.nix-profile/bin/python3 /home/mikl/sideprojects/other/nick/app.py"; + Restart = "on-failure"; + RestartSec = 5; + NoNewPrivileges = true; + PrivateTmp = true; + }; + + environment = { + TIMER_HOST = "127.0.0.1"; + TIMER_PORT = "8787"; + TIMER_DB = "/home/mikl/sideprojects/other/nick/data/timer.db"; + }; + }; +}