Merge pull request 'Optimize Hermes Nix service configuration' (#19) from fix/hermes-matrix-mautrix-deps into master
Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
@@ -41,6 +41,10 @@
|
||||
tuwunel = 3024;
|
||||
honcho = 3025;
|
||||
|
||||
# Agent infrastructure
|
||||
hermes-api = 8642;
|
||||
hermes-dashboard = 9119;
|
||||
|
||||
# Home automation
|
||||
homarr = 7575;
|
||||
|
||||
|
||||
@@ -7,31 +7,6 @@
|
||||
# Edge TTS: Seraphina — friendly, multilingual German female voice (free, no API key)
|
||||
edgeVoice = "de-DE-SeraphinaMultilingualNeural";
|
||||
|
||||
# Hermes v0.14 moved Matrix from matrix-nio to lazy-installed mautrix.
|
||||
# Lazy pip installs cannot work in the read-only Nix Python environment, so
|
||||
# provide the Matrix runtime deps declaratively and put their site-packages on
|
||||
# the gateway process PYTHONPATH at interpreter startup.
|
||||
matrixPython = pkgs.python312.withPackages (ps: let
|
||||
# Hermes lazy_deps pins this exact version. nixpkgs currently ships an
|
||||
# older aiosqlite, and lazy_deps treats version mismatches as missing.
|
||||
aiosqlite_0_22_1 = ps.aiosqlite.overridePythonAttrs (_old: rec {
|
||||
version = "0.22.1";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "omnilib";
|
||||
repo = "aiosqlite";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-voOOFo1OwaRQ3JsDHlBrngP+8ajf0kTNKXJyOaJiTs4=";
|
||||
};
|
||||
});
|
||||
in [
|
||||
(ps.mautrix.override {withOlm = true;})
|
||||
ps.markdown
|
||||
aiosqlite_0_22_1
|
||||
ps.asyncpg
|
||||
ps.aiohttp-socks
|
||||
]);
|
||||
matrixPythonPath = "${matrixPython}/lib/python3.12/site-packages";
|
||||
|
||||
# Build skills using agents flake lib for hermes user
|
||||
hermesSkills = inputs.agents.lib.mkSkills {
|
||||
inherit pkgs;
|
||||
@@ -54,17 +29,10 @@
|
||||
in {
|
||||
virtualisation.docker.enable = true;
|
||||
|
||||
# Matrix E2EE uses libolm via python-olm. libolm is archived upstream and
|
||||
# marked insecure in nixpkgs, but Hermes Matrix encrypted rooms currently
|
||||
# still require it through mautrix[encryption].
|
||||
nixpkgs.config.permittedInsecurePackages = [
|
||||
"olm-3.2.16"
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /home/hermes/.config 0755 hermes hermes -"
|
||||
"d /home/hermes/.config/tea 0755 hermes hermes -"
|
||||
"L+ /home/hermes/.config/tea/yml - - - - ${pkgs.writeText "tea-yml" ''
|
||||
"d /var/lib/hermes/.config 0755 hermes hermes -"
|
||||
"d /var/lib/hermes/.config/tea 0755 hermes hermes -"
|
||||
"L+ /var/lib/hermes/.config/tea/yml - - - - ${pkgs.writeText "tea-yml" ''
|
||||
logins:
|
||||
- name: m3ta
|
||||
url: https://code.m3ta.dev
|
||||
@@ -88,24 +56,29 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
# Ensure 'uv' is in the hermes-agent service PATH so CronJobs and terminal
|
||||
# sessions can use 'uv run' for PEP 723 scripts (e.g. garmin-daily.py).
|
||||
systemd.services.hermes-agent = {
|
||||
path = [pkgs.uv];
|
||||
environment = {
|
||||
PYTHONPATH = matrixPythonPath;
|
||||
};
|
||||
};
|
||||
|
||||
services.hermes-agent = {
|
||||
enable = true;
|
||||
addToSystemPackages = true;
|
||||
# v0.14 lazy-installs heavy optional backends by default. In the sealed
|
||||
# Nix package, include the backends this host config actively uses so the
|
||||
# gateway, Matrix bridge, memory, web search, and TTS work
|
||||
# without runtime pip/uv mutation.
|
||||
extraDependencyGroups = [
|
||||
"matrix"
|
||||
"honcho"
|
||||
"exa"
|
||||
"edge-tts"
|
||||
];
|
||||
|
||||
extraPackages = with pkgs; [
|
||||
docker
|
||||
git
|
||||
curl
|
||||
jq
|
||||
tea
|
||||
nix
|
||||
python3Minimal
|
||||
uv
|
||||
zellij
|
||||
];
|
||||
|
||||
@@ -134,7 +107,7 @@ in {
|
||||
# Bind to 0.0.0.0 so the Netbird interface can reach it.
|
||||
API_SERVER_ENABLED = "true";
|
||||
API_SERVER_HOST = "0.0.0.0";
|
||||
API_SERVER_PORT = "8642";
|
||||
API_SERVER_PORT = toString (config.m3ta.ports.get "hermes-api");
|
||||
};
|
||||
|
||||
# ── Container mode (podman) ──────────────────────────────────────────
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
# Netbird mesh VPN range — dashboard only accessible from mesh peers.
|
||||
# m3-atlas Traefik proxies to this port over Netbird.
|
||||
netbirdRange = "100.64.0.0/16";
|
||||
apiPort = config.m3ta.ports.get "hermes-api";
|
||||
dashboardPort = config.m3ta.ports.get "hermes-dashboard";
|
||||
|
||||
# Reference the hermes-agent package from the running service config
|
||||
hermesPkg = config.services.hermes-agent.package or (inputs.hermes-agent.packages.${pkgs.stdenv.hostPlatform.system}.default or pkgs.hermes-agent);
|
||||
@@ -14,10 +16,10 @@ in {
|
||||
# ── Hermes Dashboard systemd service ───────────────────────────────────
|
||||
# Web UI for managing Hermes Agent — sessions, config, kanban, cron, etc.
|
||||
#
|
||||
# Flow: Browser → dash.m3ta.dev (TLS via m3-atlas Traefik) → Netbird → :9119
|
||||
# Flow: Browser → dash.m3ta.dev (TLS via m3-atlas Traefik) → Netbird → :${toString dashboardPort}
|
||||
#
|
||||
# --insecure is required to bind 0.0.0.0 (hermes refuses non-localhost otherwise).
|
||||
# Safe because firewall restricts port 9119 to Netbird mesh only.
|
||||
# Safe because firewall restricts the dashboard/API ports to Netbird mesh only.
|
||||
systemd.services.hermes-dashboard = {
|
||||
description = "Hermes Agent Web Dashboard";
|
||||
after = ["network.target" "hermes-agent.service"];
|
||||
@@ -29,7 +31,7 @@ in {
|
||||
User = "hermes";
|
||||
Group = "hermes";
|
||||
|
||||
ExecStart = "${hermesPkg}/bin/hermes dashboard --host 0.0.0.0 --port 9119 --no-open --insecure";
|
||||
ExecStart = "${hermesPkg}/bin/hermes dashboard --host 0.0.0.0 --port ${toString dashboardPort} --no-open --insecure";
|
||||
|
||||
# Environment matching the hermes-agent service
|
||||
Environment = [
|
||||
@@ -51,15 +53,17 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
# ── Firewall: Dashboard only from Netbird mesh ─────────────────────────
|
||||
# ── Firewall: Hermes network endpoints only from Netbird mesh ──────────
|
||||
networking.firewall = {
|
||||
extraCommands = ''
|
||||
# Allow Hermes Dashboard (9119/tcp) only from Netbird mesh VPN
|
||||
ip46tables -A nixos-fw -p tcp --dport 9119 -s ${netbirdRange} -j nixos-fw-accept
|
||||
# Allow Hermes Dashboard and OpenAI-compatible API only from Netbird mesh VPN
|
||||
ip46tables -A nixos-fw -p tcp --dport ${toString dashboardPort} -s ${netbirdRange} -j nixos-fw-accept
|
||||
ip46tables -A nixos-fw -p tcp --dport ${toString apiPort} -s ${netbirdRange} -j nixos-fw-accept
|
||||
'';
|
||||
|
||||
extraStopCommands = ''
|
||||
ip46tables -D nixos-fw -p tcp --dport 9119 -s ${netbirdRange} -j nixos-fw-accept 2>/dev/null || true
|
||||
ip46tables -D nixos-fw -p tcp --dport ${toString dashboardPort} -s ${netbirdRange} -j nixos-fw-accept 2>/dev/null || true
|
||||
ip46tables -D nixos-fw -p tcp --dport ${toString apiPort} -s ${netbirdRange} -j nixos-fw-accept 2>/dev/null || true
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user