integrate stateful dockerised AI applications

This commit is contained in:
atagen 2024-05-01 15:30:22 +10:00
parent 4712934003
commit a145fad398
8 changed files with 295 additions and 20 deletions

View file

@ -8,6 +8,8 @@
}: {
imports = [
./home.nix
./programs/stable-diffusion.nix
./programs/ollama.nix
];
home = {

View file

@ -16,7 +16,6 @@ in {
./programs/firefox.nix
./programs/kitty.nix
./programs/zsh.nix
./programs/stable-diffusion.nix
./util/ez.nix
./util/firefox-webapp.nix
# inputs.plasma-manager.homeManagerModules.plasma-manager

75
home/programs/ollama.nix Normal file
View file

@ -0,0 +1,75 @@
{
config,
lib,
pkgs,
...
}: {
config.programs.firefox.webapps = {
"OpenWebUI" = {
url = "http://127.0.0.1:3021";
id = 6;
extraSettings = config.programs.firefox.profiles.default.settings;
name = "OpenWebUI Client";
hidden = true;
};
};
config.systemd.user.services = {
open-webui = {
Unit.Description = "OpenWebUI";
Service = let
docker = lib.getExe pkgs.docker;
in {
ExecStartPre = "bash -c '${docker} inspect open-webui || ${docker} create -e PORT=3021 --network host --gpus all -v ollama:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:ollama'";
ExecStart = "${docker} start open-webui";
};
};
};
config.xdg.desktopEntries = {
open-webui = {
name = "Ollama OpenWebUI";
type = "Application";
exec = "${let
notify-send = "${lib.getExe' pkgs.libnotify "notify-send"}";
systemctl = "${lib.getExe' pkgs.systemd "systemctl"}";
dex = "${lib.getExe pkgs.dex}";
curl = "${lib.getExe pkgs.curl}";
in
pkgs.writeShellScript "ollama"
''
${notify-send} "Ollama OpenWebUI" "Launching backend.."
${systemctl} --user start open-webui
attempts=0
success=false
while [[ $attempts -lt $((20*9)) ]]; do
if [[ $(${curl} http://127.0.0.1:3021) ]]; then
${notify-send} "Ollama OpenWebUI" "Launching client.."
success=true
break
else
attempts=$((attempts+1))
if [[ $(($attempts % 20)) -eq 0 ]]; then
${notify-send} "Ollama OpenWebUI" "Still launching backend.. ($((attempts/2))s)"
fi
fi
sleep 0.5
done
if [[ ! $success ]]; then
${notify-send} "Ollama OpenWebUI" "Failed to launch backend!"
${systemctl} --user kill open-webui
exit 1
fi
sleep 0.5 # give it a little time
${dex} -w ~/.nix-profile/share/applications/OpenWebUI.desktop
${notify-send} "Ollama OpenWebUI" "Shutting down."
${systemctl} --user stop open-webui
exit 0
''}";
};
};
}

View file

@ -4,7 +4,8 @@
lib,
...
}: {
# TODO: create a flake for this
# TODO: figure out if there's a meaningful way to add this to the nix store
# if nothing's reproducible should we even bother
# https://github.com/AbdBarho/stable-diffusion-webui-docker/
config.programs.firefox.webapps = {
@ -13,44 +14,72 @@
id = 5;
extraSettings = config.programs.firefox.profiles.default.settings;
name = "Stable Diffusion Client";
hidden = true;
};
};
# consider making these manually activated systemd services
config.systemd.user.services = {
stable-diffusion = {
Unit.Description = "Stable Diffusion Backend";
Service = {
WorkingDirectory = "${config.home.homeDirectory}/code/etc/stable-diffusion-webui-docker";
ExecStart = "${lib.getExe pkgs.docker} compose --profile comfy up --build";
# ExecStop = "${lib.getExe pkgs.docker} compose stop";
};
};
# stable-diffusion-dl = {}
};
config.xdg.desktopEntries = {
stable-diffusion = {
name = "Stable Diffusion Backend Start";
name = "Stable Diffusion";
type = "Application";
exec = "systemctl --user start stable-diffusion.service";
exec = "${let
notify-send = "${lib.getExe' pkgs.libnotify "notify-send"}";
systemctl = "${lib.getExe' pkgs.systemd "systemctl"}";
dex = "${lib.getExe pkgs.dex}";
curl = "${lib.getExe pkgs.curl}";
in
pkgs.writeShellScript "stable-diffusion"
''
${notify-send} "Stable Diffusion" "Launching backend.."
${systemctl} --user start stable-diffusion
attempts=0
success=false
while [[ $attempts -lt $((20*9)) ]]; do
if [[ $(${curl} http://127.0.0.1:7860) ]]; then
${notify-send} "Stable Diffusion" "Launching client.."
success=true
break
else
attempts=$((attempts+1))
if [[ $(($attempts % 20)) -eq 0 ]]; then
${notify-send} "Stable Diffusion" "Still launching backend.. ($((attempts/2))s)"
fi
fi
sleep 0.5
done
if [[ ! $success ]]; then
${notify-send} "Stable Diffusion" "Failed to launch backend!"
${systemctl} --user kill stable-diffusion
exit 1
fi
sleep 0.5 # give it a little time
${dex} -w ~/.nix-profile/share/applications/StableDiffusion.desktop
${notify-send} "Stable Diffusion" "Shutting down."
${systemctl} --user stop stable-diffusion
exit 0
''}";
};
stable-diffusion-stop = {
name = "Stable Diffusion Backend Stop";
type = "Application";
exec = "systemctl --user stop stable-diffusion.service";
};
# settings = {
# Path = "${config.home.homeDirectory}/code/etc/stable-diffusion-webui-docker";
# };
# exec = "kitty -d ${config.home.homeDirectory}/code/etc/stable-diffusion-webui-docker sh -c \"docker compose --profile comfy up --build\"";
# stable-diffusion-dl = {
# name = "Stable Diffusion Setup";
# type = "Application";
# settings = {
# Path = "${config.home.homeDirectory}/code/etc/stable-diffusion-webui-docker";
# };
# exec = "kitty --hold docker compose --profile download up --build";
# exec = "docker compose --profile download up --build";
# };
};
}

View file

@ -5,7 +5,7 @@
}: let
inherit (builtins) getAttr stringLength substring;
inherit (lib) mkOption;
inherit (lib.attrsets) mapAttrs mapAttrs' nameValuePair;
inherit (lib.attrsets) filterAttrs mapAttrs mapAttrs' nameValuePair;
inherit (lib.strings) concatStringsSep toUpper;
make-app-profiles = cfg:
@ -87,6 +87,12 @@ in {
description = "The Firefox profile ID to set.";
};
hidden = mkOption {
type = bool;
description = "Hide this webapp from the list of applications (but still generate a .desktop file).";
default = false;
};
extraArgs = mkOption {
type = listOf str;
default = [];
@ -184,7 +190,7 @@ in {
type = "Application";
exec = concatStringsSep " " ([
"${config.programs.firefox.package}/bin/firefox"
"${lib.getExe config.programs.firefox.package}"
"--name"
"${name}"
"--app-id"
@ -201,6 +207,7 @@ in {
settings = {
X-MultipleArgs = "false"; # Consider enabling, don't know what this does
StartupWMClass = "${name}";
NoDisplay = lib.boolToString cfg.hidden;
};
})
config.programs.firefox.webapps;