Jump to content

Ollama GNOME System Tray Panel 260401

From MediawikiCIT
Revision as of 16:38, 31 March 2026 by Justinaquino (talk | contribs) ("Add Ollama GNOME System Tray Panel guide")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Adding an Ollama System Tray Control to GNOME (Ubuntu)

Overview

When using Ollama locally, large language models (LLMs) are loaded directly into your GPU's VRAM for fast processing. However, Ollama keeps these models "hot" in memory for a period of time after you finish chatting. If you are running heavy models (like a 7B or 8B parameter model), this can easily consume 5GB+ of VRAM, leaving little room for gaming, video editing, or other GPU-intensive tasks.

Instead of repeatedly opening a terminal to run systemctl commands to kill the service, you can create a lightweight GNOME panel application (system tray icon). This utility provides a simple, two-click visual interface to start and stop the Ollama background service, immediately freeing up your VRAM when needed.


Features

  • One-Click Controls: Start or stop the Ollama systemd service directly from the top panel.
  • Visual Status: The icon dynamically changes to show whether Ollama is currently running () or stopped ().
  • Asynchronous Execution: Uses background threading so password prompts (pkexec) do not freeze your desktop environment.
  • Auto-Polling: Detects if Ollama was started or stopped from a terminal and updates the panel icon automatically.

Installation

Step 1: Install Prerequisites

You will need the Python bindings for GTK3 and AppIndicator to allow the script to integrate with the GNOME top panel.

Open your terminal and run:

sudo apt update
sudo apt install python3-gi python3-gi-cairo gir1.2-appindicator3-0.1

Step 2: Create the Python Script

Create a new Python file in a permanent location, such as your home directory or a dedicated scripts folder.

nano ~/ollama-panel.py

Paste the following code into the file:

#!/usr/bin/env python3
import gi
import subprocess
import threading

# Require the necessary GTK and AppIndicator versions
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GLib

class OllamaIndicator:
    def __init__(self):
        # Initialize with a placeholder icon; it will update immediately
        self.indicator = AppIndicator3.Indicator.new(
            "ollama_indicator",
            "system-run",
            AppIndicator3.IndicatorCategory.APPLICATION_STATUS
        )
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)

        self.menu = Gtk.Menu()

        # Start Button
        self.start_item = Gtk.MenuItem(label='▶ Start Ollama')
        self.start_item.connect('activate', lambda _: self.run_systemctl('start'))
        self.menu.append(self.start_item)

        # Stop Button
        self.stop_item = Gtk.MenuItem(label='⏹ Stop Ollama')
        self.stop_item.connect('activate', lambda _: self.run_systemctl('stop'))
        self.menu.append(self.stop_item)

        self.menu.append(Gtk.SeparatorMenuItem())

        # Quit Button
        quit_item = Gtk.MenuItem(label='Quit Panel App')
        quit_item.connect('activate', Gtk.main_quit)
        self.menu.append(quit_item)

        self.menu.show_all()
        self.indicator.set_menu(self.menu)

        # Run an initial status check
        self.update_status()

        # Poll systemctl every 3 seconds to catch external changes
        GLib.timeout_add_seconds(3, self.update_status)

    def get_ollama_status(self):
        # Suppress errors/output so it fails gracefully if cancelled
        result = subprocess.run(
            ["systemctl", "is-active", "ollama"],
            capture_output=True, text=True
        )
        return result.stdout.strip() == "active"

    def update_status(self):
        active = self.get_ollama_status()

        if active:
            self.indicator.set_icon_full("media-playback-start", "Ollama is running")
            self.start_item.set_sensitive(False)
            self.stop_item.set_sensitive(True)
        else:
            self.indicator.set_icon_full("media-playback-pause", "Ollama is stopped")
            self.start_item.set_sensitive(True)
            self.stop_item.set_sensitive(False)

        return True # Returning True keeps the GLib timer running

    def run_systemctl(self, command):
        def execute():
            # Run the command and wait for it to finish (or be cancelled)
            subprocess.run(["pkexec", "systemctl", command, "ollama"])
            # Schedule a UI update on the main GTK thread once done
            GLib.idle_add(self.update_status)

        # Fire in a background thread so the polkit prompt doesn't freeze the panel
        threading.Thread(target=execute, daemon=True).start()

def main():
    app = OllamaIndicator()
    Gtk.main()

if __name__ == "__main__":
    main()

Save the file and exit your text editor.

Step 3: Make the Script Executable

Grant the script permission to run as an executable program:

chmod +x ~/ollama-panel.py

You can test it immediately by running python3 ~/ollama-panel.py. An icon should appear in your top-right system tray.


Optional: Configure Passwordless Toggling

By default, clicking "Start" or "Stop" will bring up a graphical prompt asking for your sudo password. If you want to bypass this for convenience:

  1. Open the sudoers editor safely:
sudo visudo
  1. Add this line to the very bottom of the file (replace your_username with your actual Ubuntu username):
your_username ALL=(ALL) NOPASSWD: /bin/systemctl start ollama, /bin/systemctl stop ollama
  1. Save and exit.
  2. Open ~/ollama-panel.py and change the subprocess.run line inside the execute() function from "pkexec" to "sudo":
subprocess.run(["sudo", "systemctl", command, "ollama"])

Setting Up Autostart (Run on Boot)

To ensure the control panel is always available when you log in:

  1. Open the Startup Applications tool from your Ubuntu application menu.
  2. Click Add.
  3. Fill in the fields:
    • Name: Ollama Control Panel
    • Command: /usr/bin/python3 /home/YOUR_USERNAME/ollama-panel.py — ensure you use the absolute path to your script
    • Comment: System tray toggle for the Ollama service.
  4. Click Save.