Skip to content

Repository files navigation

(Local) AI Hub

A desktop control panel for what you self-host on your own machine. Local AI comes first: Ollama, Open WebUI, ComfyUI, and agent harnesses on top. Below it sits Self-Hosted Apps & Services: whatever else you run in rootless Podman, found automatically. Start and stop each one, watch live status, manage models, and see the address that actually works from your phone.

License: AGPL v3 Python 3.10+ Platform: Linux Telemetry: none

(Local) AI Hub, dark theme, showing the Local AI and Self-Hosted Apps & Services groups   (Local) AI Hub, light theme, showing the Local AI and Self-Hosted Apps & Services groups

(Local) AI Hub at a narrow window width
The stacked layout at a narrow width, the same place the LAN and Tailscale addresses matter most.

Everything stays local. No accounts, no telemetry, no analytics, nothing phones home. The only outbound actions are the "browse models" links, model updates, and the "check for a newer version" button. Each contacts one host, and only when you click it.


⚙️ Tested on

This is built and proven on one specific configuration:

  • Distro: Bazzite (Fedora Atomic base, KDE)
  • Hardware: AMD Ryzen AI MAX+ 395 "Strix Halo", Radeon 8060S iGPU (gfx1151)
  • Services: Ollama · Open WebUI · ComfyUI

Other distros, GPUs, or AI tools aren't supported yet, not a promise they won't be, just an honest label. The app's built-in Setup Check detects whether your machine matches and skips the checks plainly if it doesn't.

🚀 New here? Start with the guide

docs/GETTING_STARTED.md, a from-scratch setup for the same Bazzite + Strix Halo hardware, with two tracks: one for people using an AI assistant, and a full manual walkthrough (every command verified against a working machine).

✨ Features

  • Two clear groups: Local AI on top (the tools this app is about), Self-Hosted Apps & Services below. The second group collapses, and starts collapsed past six services, so a big homelab never buries the AI stack.
  • Your other self-hosted services, found automatically: the app asks Podman what's actually running rather than checking a list of supported names, so your Jellyfin or Nextcloud shows up the same way. Well-known services get a proper label; anything else is shown honestly by container name and port. Pods collapse to one entry, and containers you ran by hand stay out.
  • One toggle per service: start/stop anything in either group (systemd --user), live status from a real liveness check, not just "the container exists".
  • Open in browser: one click to each running web UI, always via 127.0.0.1 (never localhost).
  • Reachable at: the address that works from your phone. The app detects what this machine actually has (LAN, Tailscale with its MagicDNS name) and shows each one with a plain-language note about where it works. Nothing is invented; undetected means not shown.
  • Ollama model manager: installed models with size, an in-memory vs on-disk badge, and a real ollama pull Update.
  • ComfyUI model manager: lists what's in your model folders by type; install new models from a Hugging Face / Civitai / direct link (download → verify → filed in the right folder); per-model Update once a source is set.
  • Setup Check: one panel that verifies the iGPU flags, the Open WebUI Quadlet, the gfx1151 ROCm build, and the GGUF node, with safe one-click fixes.
  • Crash-aware: a service that dies shows "Stopped unexpectedly" with a View log button, not a silent gray.
  • Live rescan: auto + manual, so hand-added models appear without a restart.
  • Notices installs and uninstalls while it's running: install or remove a tool by any method and the card updates itself; the honest "Not installed" state appears and disappears without a restart. Driven by systemd D-Bus signals and filesystem watches, not by constant rescanning.
  • Agent layers: a harness that runs on top of your stack (currently Hermes Agent) gets its own labelled section rather than being mixed in with the base services, so it's obvious what's an engine (Ollama), what's an interface (Open WebUI), and what's an agent on top. The card states its dependency in place, shows the model and context it's configured against, and flags it clearly if that model isn't installed.
  • Check for a newer version of the app: in About, and only when you press it. No launch check, no background timer. Flatpak installs are pointed at their app store; the app never updates itself.
  • Disk space in view: how much Ollama models, ComfyUI models, container images and container volumes are using, with free space per physical device rather than the same number repeated per tool. Measured in the background, so nothing waits on it.
  • Memory in view, and a way to release it: what is resident right now and how it compares with the machine. Releasing asks Ollama to unload one model, which is exactly what ollama stop does; Ollama finishes any request already in progress first, so nothing in flight is cut off.
  • Uninstall, with a preview: every removal is shown in full before anything happens, and removing software never deletes your data. See below.
  • Light & dark: polished, and your choice persists.

🗑️ What uninstall does, and what it will not do

The uninstall preview, listing every artifact with its full path   The same preview with the separate data option ticked

Left: the preview, with data excluded and the button reading "Remove the software". Right: the same screen after ticking the separate data box, which names the exact volume and changes what the button says.

Removing software and deleting your data are different operations here, and they never share a confirmation.

Removing a service takes the container, the quadlet file, the generated systemd unit and its leftover state, the configuration folder, the cache folder, the launcher entry and the icon. Every one of them is listed with its full path and size before anything happens.

Your data is separate. Podman named volumes are excluded by default. They are listed by name with their size, and only removed if you tick a box that names the specific volume it will delete. That box is never pre-selected and never bundled into the software confirmation.

It will not:

  • Remove a container image, ever. Images are shared downloads and removing one is not needed to remove a service.
  • Remove any volume or image that something else is using. That is reported as kept, naming what else uses it.
  • Continue past a failure. It stops at the first step that does not work and tells you exactly what was and was not done.
  • Remove itself.

Some things show a disabled trash button on purpose, with the reason stated in place. Honest limits are the point:

Item Why it is disabled
Ollama Its program files live in /usr/local, outside your home and owned by root. This app never asks for root, and removing the unit and models while leaving the binary behind is a half-finished job.
ComfyUI Its program files, your models and your generated images are all inside one folder. The app cannot tell them apart well enough to remove one and keep the others.
A pod, such as Immich It is several containers, not one. Removing one member would leave the rest half configured.
A model that is in memory Release it first, then it can be removed.
Anything, while ComfyUI has a job queued Model files stay put until the queue is empty.
Anything, in the Flatpak build The sandbox has no access to systemd or podman on the host.

🖥️ Run it

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python app.py

Add it to your app launcher (icon + pinnable, no terminal):

bash scripts/install-desktop.sh

This renders the app icon into ~/.local/share/icons and installs a .desktop entry that runs the app through the venv, double-clicking just works.

🏗️ Architecture

  • UI: a local web front-end (web/) in a QWebEngineView (PySide6 + QtWebEngine), wired to Python over QWebChannel.
  • Backend: hub/services/ controls each service via systemctl --user + HTTP probes; Ollama uses its REST API, ComfyUI model provenance/updates live in hub/services/comfy_models.py. Stdlib only.
  • Layers: hub/layers/ holds harnesses that run on top of a base service. A Layer is a Service plus the key of what it depends on, so control and status are inherited; adding another harness means a subclass and one line in LAYER_CLASSES.
  • Change detection: hub/services/watch.py reconciles on systemd D-Bus signals and inotify rather than polling for installs.
  • Discovery: hub/services/containers.py enumerates rootless Podman containers, keyed on the PODMAN_SYSTEMD_UNIT label Quadlet writes; that label is also what start/stop uses, so discovered services go through the same Service class (and the same Flatpak D-Bus path) as everything else.
  • Addresses: hub/addresses.py reads interfaces through an ioctl over the stdlib rather than shelling out to ip, so it works with no external binary.
  • Adapting to another machine: service unit names and ports are in hub/services/*.py (unit= / health_url=).

📄 License

(Local) AI Hub is free and open source under the GNU Affero General Public License v3.0 (AGPLv3). You're free to use it commercially, fork it, and modify it, but if you modify it and run it as a hosted or networked service, AGPLv3 requires you to release your modified source too. That deliberately closes the loophole a permissive license leaves open for closed, hosted forks.

Release history is in CHANGELOG.md.

💬 Connect

Same links live inside the app, under About in the header.

☕ Support this project

(Local) AI Hub is free and always will be. If it's useful to you and you'd like to help keep it going, you can buy me a coffee, entirely optional, always appreciated.

Buy Me a Coffee


Made by Kamsiob · YouTube · GitHub · Website · Telegram · hello@kamsiob.com

About

A calm desktop control panel for what runs on your own Linux machine. Local AI comes first: Ollama, Open WebUI, ComfyUI and agent harnesses on top. Below it sit the self-hosted apps and services you run alongside, found automatically. Start, stop, watch real status, manage models, and see which address works from your phone.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages