aboutsummaryrefslogtreecommitdiff
path: root/hosts
diff options
context:
space:
mode:
Diffstat (limited to 'hosts')
-rw-r--r--hosts/herra/ai.nix175
-rw-r--r--hosts/herra/arion-compose.nix50
-rw-r--r--hosts/herra/configuration.nix1
3 files changed, 226 insertions, 0 deletions
diff --git a/hosts/herra/ai.nix b/hosts/herra/ai.nix
new file mode 100644
index 0000000..df93a24
--- /dev/null
+++ b/hosts/herra/ai.nix
@@ -0,0 +1,175 @@
+{
+ pkgs,
+ lib,
+ ...
+}: let
+ puid = "1000";
+ pgid = "100";
+ odysseusRepo = "https://github.com/pewdiepie-archdaemon/odysseus.git";
+ odysseusDir = "/var/lib/odysseus/src";
+in {
+ # ----------------------------
+ # Ollama (native)
+ # ----------------------------
+ services.ollama = {
+ enable = true;
+ host = "0.0.0.0";
+ port = 11434;
+ };
+
+ # ----------------------------
+ # Docker
+ # ----------------------------
+ virtualisation.docker.enable = true;
+ virtualisation.oci-containers.backend = "docker";
+
+ # ----------------------------
+ # Persistent storage
+ # ----------------------------
+ systemd.tmpfiles.rules = [
+ "d /var/lib/odysseus/data 0755 root root -"
+ "d /var/lib/odysseus/logs 0755 root root -"
+ "d /var/lib/odysseus/ssh 0755 root root -"
+ "d /var/lib/odysseus/huggingface 0755 root root -"
+ "d /var/lib/odysseus/chromadb 0755 root root -"
+ "d /var/lib/odysseus/ntfy 0755 root root -"
+ "d /var/lib/odysseus/searxng 0777 root root -"
+ "d /var/lib/odysseus/src 0755 root root -"
+ ];
+
+ # ----------------------------
+ # SearXNG config
+ # ----------------------------
+ environment.etc."odysseus/searxng/settings.yml".text = ''
+ use_default_settings: true
+ server:
+ secret_key: "change-me-openssl-rand-hex-32"
+ limiter: false
+ image_proxy: true
+ search:
+ safe_search: 0
+ formats:
+ - html
+ - json
+ '';
+
+ # ----------------------------
+ # Build Odysseus from source via systemd oneshot
+ # ----------------------------
+ systemd.services.odysseus-build = {
+ description = "Build Odysseus Docker image from source";
+ wantedBy = ["docker-odysseus.service"];
+ before = ["docker-odysseus.service"];
+ after = ["docker.service" "network-online.target"];
+ wants = ["network-online.target"];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+ path = [pkgs.git pkgs.docker];
+ script = ''
+ if [ ! -d "${odysseusDir}/.git" ]; then
+ git clone ${odysseusRepo} ${odysseusDir}
+ else
+ git -C ${odysseusDir} pull --ff-only
+ fi
+
+ NEW_HASH=$(git -C ${odysseusDir} rev-parse HEAD)
+ OLD_HASH=$(cat /var/lib/odysseus/.last-built-commit 2>/dev/null || echo "")
+
+ if [ "$NEW_HASH" != "$OLD_HASH" ] || ! docker image inspect odysseus:local &>/dev/null; then
+ echo "Building odysseus image at commit $NEW_HASH..."
+ docker build -t odysseus:local ${odysseusDir}
+ echo "$NEW_HASH" > /var/lib/odysseus/.last-built-commit
+ else
+ echo "Image up to date at $OLD_HASH, skipping build."
+ fi
+ '';
+ };
+
+ # ----------------------------
+ # Containers
+ # ----------------------------
+ virtualisation.oci-containers.containers = {
+ odysseus-chromadb = {
+ image = "chromadb/chroma:latest";
+ ports = ["127.0.0.1:8100:8000"];
+ volumes = ["/var/lib/odysseus/chromadb:/chroma/chroma"];
+ environment.ANONYMIZED_TELEMETRY = "FALSE";
+ };
+
+ odysseus-searxng = {
+ image = "searxng/searxng:latest";
+ ports = ["127.0.0.1:8080:8080"];
+ volumes = [
+ "/var/lib/odysseus/searxng:/etc/searxng"
+ "/etc/odysseus/searxng/settings.yml:/etc/searxng/settings.yml:ro"
+ ];
+ environment.SEARXNG_BASE_URL = "http://localhost:8080/";
+ };
+
+ odysseus-ntfy = {
+ image = "binwiederhier/ntfy";
+ cmd = ["serve"];
+ ports = ["127.0.0.1:8091:80"];
+ volumes = ["/var/lib/odysseus/ntfy:/var/cache/ntfy"];
+ environment.NTFY_BASE_URL = "http://localhost:8091";
+ };
+
+ odysseus = {
+ image = "odysseus:local";
+ ports = ["127.0.0.1:7000:7000"];
+ volumes = [
+ "/var/lib/odysseus/data:/app/data"
+ "/var/lib/odysseus/logs:/app/logs"
+ "/var/lib/odysseus/ssh:/app/.ssh"
+ "/var/lib/odysseus/huggingface:/app/.cache/huggingface"
+ ];
+ environment = {
+ APP_BIND = "0.0.0.0";
+ APP_PORT = "7000";
+ AUTH_ENABLED = "true";
+ PUID = puid;
+ PGID = pgid;
+ SEARXNG_INSTANCE = "http://host.docker.internal:8080";
+ CHROMADB_HOST = "host.docker.internal";
+ CHROMADB_PORT = "8000";
+ OLLAMA_BASE_URL = "http://host.docker.internal:11434/v1";
+ };
+ extraOptions = [
+ "--add-host=host.docker.internal:host-gateway"
+ "--pull=never"
+ ];
+ dependsOn = ["odysseus-chromadb" "odysseus-searxng" "odysseus-ntfy"];
+ };
+ };
+
+ # Restart policy (mkForce overrides oci-containers' default "always")
+ systemd.services = {
+ docker-odysseus-chromadb.serviceConfig.Restart = lib.mkForce "on-failure";
+ docker-odysseus-searxng.serviceConfig.Restart = lib.mkForce "on-failure";
+ docker-odysseus-ntfy.serviceConfig.Restart = lib.mkForce "on-failure";
+ docker-odysseus.serviceConfig.Restart = lib.mkForce "on-failure";
+ };
+
+ # ----------------------------
+ # Nginx + local DNS
+ # ----------------------------
+ services.nginx = {
+ enable = true;
+ virtualHosts."ai.local" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:7000";
+ proxyWebsockets = true;
+ extraConfig = ''
+ proxy_read_timeout 300s;
+ proxy_connect_timeout 75s;
+ '';
+ };
+ };
+ };
+
+ networking.hosts."127.0.0.1" = ["ai.local"];
+ networking.firewall.allowedTCPPorts = [80];
+ networking.firewall.interfaces.docker0.allowedTCPPorts = [11434];
+}
diff --git a/hosts/herra/arion-compose.nix b/hosts/herra/arion-compose.nix
new file mode 100644
index 0000000..daa4077
--- /dev/null
+++ b/hosts/herra/arion-compose.nix
@@ -0,0 +1,50 @@
+{pkgs, ...}: {
+ project.name = "odysseus";
+
+ services.odysseus.service = {
+ image = "ghcr.io/pewdiepie-archdaemon/odysseus:latest";
+
+ ports = [
+ "7000:7000"
+ ];
+
+ volumes = [
+ "/srv/odysseus/data:/app/data"
+ ];
+
+ environment = {
+ AUTH_ENABLED = "true";
+
+ LLM_HOST = "host.docker.internal:11434";
+
+ CHROMADB_HOST = "chromadb";
+
+ SEARXNG_INSTANCE = "http://searxng:8080";
+ };
+
+ extra_hosts = [
+ "host.docker.internal:host-gateway"
+ ];
+
+ depends_on = [
+ "chromadb"
+ "searxng"
+ ];
+ };
+
+ services.chromadb.service = {
+ image = "chromadb/chroma:latest";
+
+ volumes = [
+ "/srv/odysseus/chroma:/chroma/chroma"
+ ];
+ };
+
+ services.searxng.service = {
+ image = "searxng/searxng:latest";
+ };
+
+ services.ntfy.service = {
+ image = "binwiederhier/ntfy:latest";
+ };
+}
diff --git a/hosts/herra/configuration.nix b/hosts/herra/configuration.nix
index f3df657..4403d12 100644
--- a/hosts/herra/configuration.nix
+++ b/hosts/herra/configuration.nix
@@ -11,6 +11,7 @@
./drivers.nix
./steam.nix
./network.nix
+ ./ai.nix
];
networking.hostName = "herra";