This commit is contained in:
ashisgreat22 2026-01-14 21:24:19 +01:00
commit 2be8de47fa
87 changed files with 11501 additions and 0 deletions

View file

@ -0,0 +1,139 @@
# Open WebUI Module (System)
# Provides: Open WebUI chat interface as system container
#
# Usage:
# myModules.openWebUI = {
# enable = true;
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.openWebUI;
in
{
options.myModules.openWebUI = {
enable = lib.mkEnableOption "Open WebUI chat interface (System Service)";
image = lib.mkOption {
type = lib.types.str;
default = "ghcr.io/open-webui/open-webui:main";
description = "Open WebUI container image";
};
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/open-webui";
description = "Path to Open WebUI data directory";
};
port = lib.mkOption {
type = lib.types.port;
default = 3000;
description = "Host port for Open WebUI";
};
# Networking Defaults:
# - Ollama is on the SAME system network (antigravity-net), so we use container name 'ollama'.
# - Unified Router is a USER container, so we must access via Host gateway.
ollamaUrl = lib.mkOption {
type = lib.types.str;
default = "http://ollama:11434";
description = "URL to Ollama API (Internal Container Network)";
};
openaiBaseUrl = lib.mkOption {
type = lib.types.str;
# 10.88.0.1 is default podman gateway, or use host.containers.internal if available
default = "http://host.containers.internal:6767/v1";
description = "URL to OpenAI-compatible API (Unified Router on Host)";
};
envFile = lib.mkOption {
type = lib.types.str;
default = "/run/secrets/open_webui_env";
description = "Path to environment file with secrets";
};
apiKeyEnvFile = lib.mkOption {
type = lib.types.str;
default = "/run/secrets/rendered/api_key.env";
description = "Path to API key environment file";
};
};
config = lib.mkIf cfg.enable {
# Ensure data directory exists
systemd.tmpfiles.rules = [
"d ${cfg.dataDir} 0750 root root -"
];
systemd.services.open-webui = {
description = "Open WebUI Container (System)";
after = [
"network-online.target"
"ollama.service"
];
wants = [ "network-online.target" ];
requires = [ "ollama.service" ]; # It depends on Ollama for local inference often
serviceConfig = {
Restart = "always";
# Hardening
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
ProtectKernelTunables = false;
ProtectControlGroups = false; # Podman needs cgroups
ProtectKernelModules = true;
# Allow Podman to write to state and data
ReadWritePaths = [
"/var/lib/containers"
"/run"
"/etc/containers" # Network configs live here
cfg.dataDir
];
# ExecStartPre to cleanup
ExecStartPre = [
"-${pkgs.podman}/bin/podman stop open-webui"
"-${pkgs.podman}/bin/podman rm open-webui"
"${pkgs.podman}/bin/podman pull ${cfg.image}"
"${pkgs.podman}/bin/podman network create antigravity-net --ignore"
# Fix ownership for UserNS (container user maps to host UID 200000)
"${pkgs.coreutils}/bin/chown -R 200000:200000 ${cfg.dataDir}"
];
ExecStart = ''
${pkgs.podman}/bin/podman run --rm --name open-webui \
--network=antigravity-net \
--dns=8.8.8.8 \
--userns=auto \
-e ENABLE_PERSISTENT_CONFIG=True \
-e OPENAI_API_BASE_URL=${cfg.openaiBaseUrl} \
-e OLLAMA_BASE_URL=${cfg.ollamaUrl} \
-e ENABLE_RAG_WEB_SEARCH=True \
-e RAG_WEB_SEARCH=True \
-e RAG_WEB_SEARCH_ENGINE=duckduckgo \
-e RAG_WEB_SEARCH_RESULT_COUNT=3 \
-e ENABLE_RAG=True \
--env-file=${cfg.envFile} \
--env-file=${cfg.apiKeyEnvFile} \
-v ${cfg.dataDir}:/app/backend/data:U \
--add-host=host.containers.internal:host-gateway \
-p 127.0.0.1:${toString cfg.port}:8080 \
${cfg.image}
'';
ExecStop = "${pkgs.podman}/bin/podman stop open-webui";
};
wantedBy = [ "multi-user.target" ];
};
};
}