. | .
\|/
.--- O ---.
/ /|\ \
' / | \ '
. | .
Fresh Linux Mint → Working AI Cockpit
Step-by-step setup for a Linux Mint 22 / Ubuntu 24.04 machine. Each step has a verification checkpoint. Do not skip steps. If a step fails, the Troubleshooting section at the end has fixes.
CI-verified — an unattended end-to-end run of install_cockpit.sh
passes on a real Linux Mint/Ubuntu runner (GitHub Actions).
/home/dario/... by default; if your username differs,
edit the installation paths accordinglyGet this bundle ready in ~/Downloads/:
cockpit-bundle/
├─ index.html
├─ bridge.php
├─ files.php
├─ status.php
├─ models.php
├─ saver.php
├─ session.php
├─ config.php
├─ library.php
├─ paths.json
├─ search.php
├─ export.php
├─ import.php
├─ version.php
├─ VERSION
├─ capabilities.php
├─ orchestrator.php
├─ workers.php
├─ workers_providers.json
├─ tools.php
├─ tools_builtins.tar.gz
├─ cockpit_builtins.tar.gz
├─ install_capabilities.sh
├─ install_cockpit.sh
├─ build_cockpit_tarball.sh
├─ cockpit_start.sh
├─ cockpit_stop.sh
├─ agent_loop.sh
└─ crud_executor.sh
The cockpit ships an automated install_cockpit.sh script
that handles most of these steps end-to-end. This guide walks
through the manual sequence — useful if you want to understand
what’s happening or if the auto-installer fails partway.
Steps 1–12 below are written for Linux Mint/Ubuntu. Cockpit itself is just Apache + PHP + Bash + tmux — it runs the same way on any OS that can provide those, with the caveats below.
CI-verified — an unattended end-to-end run of install_cockpit_macos.sh
passes on a real Apple Silicon runner (GitHub Actions). If anything looks
different on your own Mac, let us know.
Genuinely native-capable — no virtualization needed. Apple removed PHP and disabled Apache by default since macOS 12, but both install cleanly via Homebrew:
# 1. Install Homebrew if you don't have it: https://brew.sh
brew install httpd php tmux ffmpeg pandoc
# 2. whisper.cpp — build with the Metal backend (not Vulkan, that's Linux-only)
git clone https://github.com/ggml-org/whisper.cpp
cd whisper.cpp && make
# 3. Ollama — official native app, Apple Silicon Metal-accelerated
# https://ollama.com/download/mac
# 4. Start Apache (httpd), point its docroot at the cockpit-bundle folder,
# same as Step 5–6 below — paths differ slightly (/opt/homebrew/... on
# Apple Silicon, /usr/local/... on Intel) but the steps are the same.
Everything else — Steps 6 through 12 — is identical to the Linux instructions once Apache/PHP/tmux are running. Apple Silicon (M-series) is fully supported; Intel Macs work too but aren't specifically tested.
NOT TESTED YET
Written and reviewed carefully, but install_windows.ps1 hasn't
actually been run on a real Windows machine yet — please
let us know how it goes if you try it.
Native Windows can't run this stack as-is —
agent_loop.sh is built around tmux, which has no
real Windows equivalent. The supported path is
WSL2 (Windows Subsystem for Linux): a real Ubuntu
environment running alongside Windows, reachable from your normal Windows
browser at localhost.
install_windows.ps1 (in the download bundle) does the whole
Windows-side setup for you: enables WSL2, installs Ubuntu-24.04, creates the
Linux user unattended (skips WSL's normal interactive
first-run wizard, generates a random password and shows it to you once),
installs VS Code if you don't have it, and installs the
WSL Remote extension — required, not optional, for
comfortably editing project files with native Windows tooling later. Run it
from an elevated PowerShell:
# Right-click PowerShell → "Run as Administrator", then:
.\install_windows.ps1
It hands off to install_cockpit.sh inside WSL for the actual
app install — from there it's identical to the Linux instructions.
# 1. Install WSL2 + Ubuntu (PowerShell, as Administrator)
wsl --install -d Ubuntu-24.04
# 2. Reboot when prompted, then open the new "Ubuntu" Start Menu entry
# and finish the Ubuntu first-run (create a Linux username/password —
# unrelated to your Windows login).
# 3. Inside that Ubuntu shell, follow Steps 1–12 of this guide exactly
# as written — it's a real Ubuntu 24.04, nothing Windows-specific
# from here on. Access the cockpit from your normal Windows browser
# at http://localhost/cockpit/ once Apache's running (WSL2 forwards
# localhost automatically).
Then install VS Code + its "WSL" (Remote-WSL) extension yourself, and
use Ctrl+Shift+P → "WSL: Connect to WSL" to open project
folders with full native-tool convenience at full WSL-native filesystem
speed — this is the setup we recommend project files live under (inside
WSL's own filesystem), not on the Windows side reached via
/mnt/c/..., which has real I/O overhead for the kind of
many-small-file CRUD Cockpit's agents do.
Ollama — run it natively on Windows, not inside WSL.
Ollama has a real native Windows installer with full NVIDIA CUDA GPU
support — better performance than running it inside the WSL2 virtual
machine. Install it normally from
ollama.com/download/windows,
then point Cockpit's Ollama connection (inside WSL) at the Windows
host's IP instead of localhost:
# Inside WSL, find the Windows host IP:
cat /etc/resolv.conf | grep nameserver
# → use that IP with Ollama's port, e.g. http://172.x.x.x:11434
# Set OLLAMA_HOST=0.0.0.0 on the Windows side (System Environment
# Variables) so it accepts connections from WSL, not just localhost.
WSL2's own machine identity is not stable — reinstalling
the Ubuntu distro (or certain Windows updates) resets it, which would make
Cockpit's SaaS licensing think it's a brand-new machine each time. To avoid
that, copy the Windows-native cockpit_auth.exe build to a
fixed path Windows and WSL can both see, and Cockpit will automatically
prefer it for machine identification (falls back to the normal Linux
binary if this isn't set up — nothing breaks either way):
# From Windows (PowerShell or File Explorer):
mkdir C:\CockpitAuth
copy cockpit_auth.exe C:\CockpitAuth\cockpit_auth.exe
# That's it — Cockpit (running in WSL) detects WSL automatically and
# reaches this .exe at /mnt/c/CockpitAuth/cockpit_auth.exe.
NOT TESTED YET Written and reviewed carefully, but this bundle hasn't actually been built/run end-to-end yet — please let us know how it goes if you try it.
One Dockerfile + docker-compose.yml, same on
both OSes — Docker Desktop already runs on WSL2 (Windows) or Apple's
virtualization framework (macOS), so this sidesteps writing separate
native/WSL2/Homebrew instructions per OS. Ollama and LocalAI both
run inside the same container as Cockpit, not as separate ones —
the app's PHP backends call both at hardcoded local addresses
(127.0.0.1:11434 / 127.0.0.1:8080), not a
configurable host, so split containers wouldn't be reachable. Both agents'
models persist in their own named Docker volumes across rebuilds.
Download the Docker bundle from the download
page (separate small zip — Dockerfile, compose file, entrypoint script, and
a step-by-step README; it doesn't duplicate the app itself, you extract the
main tarball's web/ folder alongside it). Not yet published to
Docker Hub, so you build locally:
docker compose build # first time, or after updating web/
docker compose up -d
# One-time: authenticate the agent CLIs
docker compose exec cockpit su - cockpit -c claude
docker compose exec cockpit su - cockpit -c gemini
# Then open in your normal browser:
# http://localhost:8080
GPU passthrough to Ollama only works via Docker on a Linux host with the
NVIDIA Container Toolkit (uncomment the deploy: block in
docker-compose.yml) — Docker Desktop on Windows/macOS doesn't
pass a GPU through to containers, so Ollama runs CPU-only there, fine for
small (1–4B) models.
CI-verified — an unattended end-to-end run of install_cockpit.sh
passes on a real ARM64 runner (GitHub Actions).
A Pi running 64-bit Raspberry Pi OS (Debian-based) is full, real Linux — Apache, PHP, bash, and tmux all work exactly as they do on any x86_64 Linux box. Steps 1–12 of this guide apply unchanged — there's no separate "Pi edition" of the install process. A Pi is also a legitimate, popular way to host Ollama itself as a small always-on local model server, even for other machines on your network to reach.
The one Pi-specific piece is cockpit_auth — the compiled
SaaS-licensing binary needs its own ARM build (a Pi can't run the x86_64
binary). That build now exists — see the download page for the ARM Linux
binary alongside the x86_64/Windows/macOS ones.
Realistic expectations: a Pi 4/5 with 8GB RAM can run small Ollama models (1–4B parameters) at reasonable speed for CRUD-style combo work; it is not going to run anything comparable to a desktop GPU for larger models — treat it as a small-model or remote-Ollama-target machine, not a general-purpose Cockpit workstation replacement.
The Everywhere tier lets a phone or any other browser talk to a Cockpit
already running on your home rig, without port-forwarding or a static IP.
Your rig has no open port; both sides poll a small queue on
cockpit.ruggi.site over plain HTTPS — nothing to configure on
your router.
Status: built, not yet deployed. The relay server, the home-rig poller, and the phone page all exist in the codebase as of this guide's last update, but the database schema hasn't been run against the live server yet and none of it has been tested end-to-end. Treat this section as "how it will work", not a guarantee it's live right now.
Settings → Account.~/scripts/cockpit_data/relay_poller_credentials.json
with your local Cockpit login (the same username/password you use to open
the web UI on this machine):
{"username": "your-local-username", "password": "your-local-password"}
This lets the relay poller submit prompts to your own local Cockpit the
same way your browser does — it's a local secret file, never uploaded
anywhere, same as the Gemini API key file.~/scripts/relay_start.sh (stop it with
~/scripts/relay_stop.sh). It no-ops safely if you're not
signed in or not on an Everywhere-capable tier.Open cockpit.ruggi.site/relay.html, sign in with the same
account, pick your rig from the list (skipped automatically if you only
have one), and send a message — it runs on your home rig's Claude/Gemini/
Ollama session exactly as if you'd typed it there, and the reply streams
back to your phone. A green dot means the rig's poller checked in within
the last 30 seconds; grey means it's offline or not started.
AI Cockpit runs on Linux, ARM Linux, macOS, and Windows (via WSL2). Every other system — Android, iOS, ChromeOS, anything else — connects through the Everywhere relay page on the site (above) instead: no install, just a browser and a free account with the Everywhere tier.
Install Apache, PHP, and the supporting CLI tools that the cockpit depends on:
sudo apt update
sudo apt install -y nala
sudo nala install -y \
apache2 \
php8.3 \
php8.3-cli \
php8.3-curl \
php8.3-mbstring \
php8.3-xml \
php8.3-zip \
libapache2-mod-php8.3 \
tmux \
jq \
curl \
git \
util-linux \
xed \
zsh \
build-essential \
ca-certificatesapache2 -v # Should show 2.4.x
php -v # Should show 8.3.x
tmux -V # Should show 3.x or higher
jq --version # Should show jq-1.6 or 1.7
which curl # Should show /usr/bin/curlIf any command says “not found”, re-run the install for that package.
bridge.php,
workers.php, orchestrator.php for HTTPsearch.php
(better than regex for HTML scraping)Node.js is needed for npx (which launches MCP servers)
and for the official Claude Code and Gemini CLI tools.
# NodeSource repository for current LTS
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo nala install -y nodejs
# Set up a global npm prefix in user-space (avoids sudo for global installs)
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
# Add to PATH (zsh)
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrcReload your shell config or open a fresh terminal.
node --version # Should show v20.x
npm --version # Should show 10.x
echo $PATH | tr ':' '\n' | grep npm-global
# Should show /home/<you>/.npm-global/binInstall the three CLI tools the cockpit dispatches to:
# Anthropic Claude Code
npm install -g @anthropic-ai/claude-code
# Google Gemini CLI
npm install -g @google/gemini-cli
# (Ollama is installed in Step 4)You’ll need to authenticate each one before the cockpit can use it:
# Claude — opens a browser for OAuth, you sign in to your Anthropic account
claude
# Gemini — likewise, OAuth flow with your Google account
geminiAfter both authenticate successfully, you can Ctrl-D out
of each.
claude --version # Should show a version string
gemini --version # Likewise
# Sanity smoke tests
echo "Say hello in one word" | claude --print
echo "Say hello in one word" | gemini --promptBoth should return a response within 5–15 seconds.
# Ollama installer — official one-liner
curl -fsSL https://ollama.com/install.sh | sh
# Configure non-default model storage location
mkdir -p "$HOME/ollama/models"
sudo systemctl edit ollama.serviceIn the editor that opens, paste:
[Service]
Environment="OLLAMA_MODELS=/home/dario/ollama/models"Save and exit. Then:
sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo systemctl enable ollama
# Also export for interactive shells
echo 'export OLLAMA_MODELS="$HOME/ollama/models"' >> ~/.zshrc
echo 'export OLLAMA_MODELS="$HOME/ollama/models"' >> ~/.bashrcThe cockpit’s default tier-1 recommendations:
# Tier 1 — best for CRUD and context (3 GB VRAM)
ollama pull qwen2.5-coder:3b
ollama pull qwen2.5-coder:7b
# Optional — tool-calling fine-tune
ollama pull MFDoom/deepseek-r1-tool-calling:7bollama list # Should list pulled models
ollama show qwen2.5-coder:3b # Should show model details
# Smoke test
echo "Say hello in one word" | ollama run qwen2.5-coder:3bIf ollama list shows the storage path is
/usr/share/ollama/..., the custom path didn’t take effect.
Re-check the systemd override file:
systemctl cat ollama.service | grep OLLAMA_MODELSSkip this if you only plan to use Ollama. Dual mode (Card 3 — both backends genuinely in parallel, for chat and Power Combos) needs LocalAI actually running too. The automated installer does all of this for you; here's the manual equivalent.
# Download the checksum-verified binary (Linux amd64 shown — see
# install_cockpit.sh for the arm64 asset/checksum)
mkdir -p ~/.local/bin
curl -fL https://github.com/mudler/LocalAI/releases/download/v4.7.1/local-ai-v4.7.1-linux-amd64 \
-o ~/.local/bin/local-ai
chmod +x ~/.local/bin/local-ai
# Verify the checksum before trusting it
echo "2a4ccf4cd7ecc76fb6dde8d847a6d1448b67d7cf84fdcb4285cd002f42a9c801 $HOME/.local/bin/local-ai" | sha256sum -c -
mkdir -p ~/localai/models ~/localai/data ~/localai/backends
sudo systemctl edit --force --full localai.service
In the editor that opens, paste (LocalAI's own paths default to CWD-relative, which breaks under systemd — every path below is explicit so it never depends on the caller's working directory):
[Unit]
Description=LocalAI Service
After=network-online.target
[Service]
WorkingDirectory=/home/YOUR_USERNAME
ExecStart=/home/YOUR_USERNAME/.local/bin/local-ai run --address 127.0.0.1:8080
Environment="LOCALAI_MODELS_PATH=/home/YOUR_USERNAME/localai/models"
Environment="LOCALAI_DATA_PATH=/home/YOUR_USERNAME/localai/data"
Environment="LOCALAI_BACKENDS_PATH=/home/YOUR_USERNAME/localai/backends"
User=YOUR_USERNAME
Group=YOUR_USERNAME
Restart=always
RestartSec=3
[Install]
WantedBy=default.target
Save and exit, replacing YOUR_USERNAME above with your
actual username first. Then:
sudo systemctl daemon-reload
sudo systemctl enable --now localai
# Wait for it to come up, then confirm
curl http://127.0.0.1:8080/
LocalAI has no pull command — models are requested through
its own HTTP API. The cockpit's default suggestions (LocalAI equivalents of
the Ollama Tier-1 set above, same job/size class, run through LocalAI's
llama.cpp backend instead):
curl -X POST http://127.0.0.1:8080/models/apply \
-H "Content-Type: application/json" \
-d '{"id":"qwen2.5-coder-3b-instruct"}'
# Returns a job uuid — poll it until "processed":true
curl http://127.0.0.1:8080/models/jobs/<uuid>
Other suggested ids: llama-3.2-3b-instruct,
deepseek-r1-distill-qwen-1.5b, qwen2.5-7b-instruct,
phi-4-mini-instruct. If an id 404s, browse
http://127.0.0.1:8080/models/available
on the running instance for the exact current gallery id.
curl http://127.0.0.1:8080/v1/models # Should list pulled models
systemctl status localai # Should be active (running)
# Smoke test
curl http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"qwen2.5-coder-3b-instruct","messages":[{"role":"user","content":"Say hello in one word"}]}'
The cockpit runs as a normal Apache vhost at
/var/www/html/cockpit/.
# Make sure mod_php is enabled
sudo a2enmod php8.3
sudo a2enmod rewrite # Used by some PHP endpoints
# Set timezone in PHP so dates are correct
sudo bash -c 'cat > /etc/php/8.3/apache2/conf.d/99-cockpit.ini' << 'EOF'
date.timezone = Asia/Jerusalem
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 300
EOF
# Same settings for CLI PHP
sudo cp /etc/php/8.3/apache2/conf.d/99-cockpit.ini /etc/php/8.3/cli/conf.d/
# Restart Apache
sudo systemctl restart apache2
sudo systemctl enable apache2# Apache should respond
curl -I http://localhost/ # Should return HTTP/1.1 200 OK
# PHP should be enabled
echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/phpinfo.php > /dev/null
curl -s http://localhost/phpinfo.php | grep "PHP Version"
# Should show "PHP Version => 8.3.x"
sudo rm /var/www/html/phpinfo.php
# Verify timezone
php -r 'echo date("c"), "\n";'
# Should show current time in your zoneDeploy the cockpit’s web files to
/var/www/html/cockpit/:
# Web root for cockpit
sudo mkdir -p /var/www/html/cockpit
# Copy all PHP files, the HTML, JSON catalogs, and VERSION
cd ~/Downloads/cockpit-bundle
sudo cp \
index.html \
bridge.php files.php status.php models.php saver.php \
session.php config.php library.php paths.json \
search.php export.php import.php version.php VERSION \
capabilities.php orchestrator.php workers.php tools.php \
workers_providers.json \
/var/www/html/cockpit/
# Extract built-in capability and tool definitions
sudo tar -xzf cockpit_builtins.tar.gz -C /var/www/html/cockpit/
sudo tar -xzf tools_builtins.tar.gz -C /var/www/html/cockpit/
# Scripts that run as the user via tmux
mkdir -p ~/scripts
cp \
cockpit_start.sh cockpit_stop.sh \
agent_loop.sh crud_executor.sh \
install_capabilities.sh \
~/scripts/
chmod +x ~/scripts/*.sh
# Cockpit data directory
mkdir -p ~/scripts/cockpit_data/{library,snippets,sources,code,approvals,capabilities/_builtin,plans,workers_state,tools,tools_outputs,_standalone}
# Projects root
mkdir -p ~/Software/Programing/LocalAIProjsls /var/www/html/cockpit/ # Should list all .php and .html files
ls ~/scripts/ # Should list shell scripts
ls ~/scripts/cockpit_data/ # Should show empty subdirsApache (running as www-data) needs read access to the
cockpit data and tmux socket. Your user (running as dario)
needs write access. The bridge between these is the
www-data group.
# Add www-data group membership for shared file access
sudo chgrp -R www-data /var/www/html/cockpit/
sudo chmod -R g+rX /var/www/html/cockpit/
sudo chgrp -R www-data ~/scripts/cockpit_data/
sudo chmod -R g+rwX ~/scripts/cockpit_data/
# tmux socket lives in /tmp; needs group access from www-data
# (cockpit_start.sh creates this on each run with the right perms)
# Add www-data to your group so it can read your home dir prefix
sudo usermod -a -G $USER www-data
# Allow www-data to invoke the cockpit_*.sh scripts without password
sudo bash -c 'cat > /etc/sudoers.d/cockpit' << EOF
www-data ALL=(${USER}) NOPASSWD: ${HOME}/scripts/cockpit_start.sh
www-data ALL=(${USER}) NOPASSWD: ${HOME}/scripts/cockpit_stop.sh
EOF
sudo chmod 440 /etc/sudoers.d/cockpit# As www-data, can it read cockpit_data?
sudo -u www-data ls ~/scripts/cockpit_data/
# Should list directories without error
# Validate sudoers without breaking the system
sudo visudo -cf /etc/sudoers.d/cockpit
# Should say "/etc/sudoers.d/cockpit: parsed OK"Capability definitions ship as a tarball; deploy them to
cockpit_data:
cd ~/Downloads/cockpit-bundle
BUILTINS_SOURCE="$PWD/cockpit_builtins" ~/scripts/install_capabilities.shThis copies five built-in capabilities (filesystem, git, web-search, web-fetch, ssh) into:
~/scripts/cockpit_data/capabilities/_builtin/
ls ~/scripts/cockpit_data/capabilities/_builtin/
# Should list 5 directories: filesystem, git, ssh, web-fetch, web-search
# Each should contain CAP.json + README.md
for d in ~/scripts/cockpit_data/capabilities/_builtin/*/; do
echo "$(basename $d):"
ls "$d"
doneWithout these binaries, the TOOLS card in the cockpit will show “no tools detected”. Install whichever you’ll use:
# Audio/video — almost always wanted
sudo nala install -y ffmpeg
# Speech-to-text — large download, ~1 GB for the base model
sudo nala install -y python3-pip
pip install --user openai-whisper # Or: nala install whisper
# Document conversion
sudo nala install -y pandoc texlive-xetex texlive-fonts-recommended
# texlive needed for md→pdfffmpeg -version | head -1 # Should show ffmpeg N.x.x
whisper --help | head -3 # Should show Whisper usage
pandoc --version | head -1 # Should show pandoc 3.xIf any are missing, you can still launch the cockpit — Tools will show them as “✗ not found” and you can install later. The cockpit’s Detect button in Tools settings re-scans whenever you click it.
sudo nala install imagemagickpip install --user yt-dlpsudo nala install calibreThese don’t ship with built-in tool definitions but you can add them via the “+” button in Tools settings.
Time to start the cockpit:
~/scripts/cockpit_start.shYou should see output like:
Starting cockpit sessions...
Claude session: cockpit_claude
Gemini session: cockpit_gemini
Ollama session: cockpit_ollama
tmux socket: /tmp/cockpit_tmux.sock
Apache: ready
Cockpit ready: http://localhost/cockpit/
Open the cockpit in Brave:
brave-browser http://localhost/cockpit/If this works, you’re done. The next steps are optional personalization.
If you want to use online LLM providers as workers:
Recommended starting point: Groq is free with generous limits and makes a good first test. Once you have a key, smoke-test it via:
xdg-settings set default-web-browser brave-browser.desktopCreate a desktop entry that launches cockpit_start.sh
and opens Brave to the cockpit URL:
mkdir -p ~/.config/autostart
cat > ~/.config/autostart/cockpit.desktop << 'EOF'
[Desktop Entry]
Type=Application
Name=AI Cockpit
Exec=bash -c '$HOME/scripts/cockpit_start.sh && sleep 2 && brave-browser http://localhost/cockpit/'
Icon=preferences-system
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
StartupNotify=false
EOFThe cockpit has its own dark theme baked in. No system-level config needed.
Edit ~/scripts/cockpit_data/last_project.txt to set the
project that opens by default each time:
echo "myproject" > ~/scripts/cockpit_data/last_project.txt# Permissions on the cockpit directory
sudo chown -R dario:www-data /var/www/html/cockpit/
sudo chmod -R g+rX /var/www/html/cockpit/
# Apache config — make sure /var/www/html is allowed
grep -A3 "Directory /var/www/" /etc/apache2/apache2.conf
# Should include "Require all granted"The PHP error log usually has the answer:
sudo tail -50 /var/log/apache2/error.logCommon causes:
sudo nala install php8.3-curl && sudo systemctl restart apache2php -l /var/www/html/cockpit/bridge.php# Check what sessions exist
tmux -S /tmp/cockpit_tmux.sock ls 2>&1
# If empty, restart cockpit
~/scripts/cockpit_stop.sh && ~/scripts/cockpit_start.sh
# If permission denied, the socket has wrong group
sudo chgrp www-data /tmp/cockpit_tmux.sock
sudo chmod 660 /tmp/cockpit_tmux.sockBoth CLIs need a working browser OAuth flow:
# From a desktop environment with a browser available
claude # Will print an auth URL; open it in your browser, sign in
gemini # Same flow, separate authIf you’re SSHing in headlessly, you’ll need to do the auth on the machine’s actual desktop session first.
# Confirm models exist
ollama list
# If empty, pull the defaults:
ollama pull qwen2.5-coder:3b
# Confirm OLLAMA_MODELS is being honored
ls ~/ollama/models/ # Should show downloaded blobs
# If models live in /usr/share/ollama/.ollama/, the systemd override didn't apply
sudo systemctl edit ollama.service # Re-set the Environment line
sudo systemctl daemon-reload && sudo systemctl restart ollama# Confirm the service is actually running
systemctl status localai
# Confirm models exist
curl http://127.0.0.1:8080/v1/models
# If empty, pull a default
curl -X POST http://127.0.0.1:8080/models/apply \
-H "Content-Type: application/json" \
-d '{"id":"qwen2.5-coder-3b-instruct"}'
# Confirm LOCALAI_MODELS_PATH is being honored
ls ~/localai/models/ # Should show downloaded files
# If the service won't start, check the unit for typos in the paths
systemctl cat localai.service
journalctl -u localai -n 50 --no-pager
# Verify the binaries are in PATH that Apache can see
sudo -u www-data which ffmpeg
sudo -u www-data which whisper
sudo -u www-data which pandoc
# If www-data can't see them but you can, the binaries are in a path
# www-data doesn't search. Either:
# (a) Use Tools settings to set absolute path
# (b) Add the path to /etc/environment so it's system-wideAPI key issue. Re-generate the key on the provider’s site, paste it into Workers settings, save.
Rate limited. Wait a few minutes or switch providers. The cockpit’s usage tracker shows your call counts per provider in the settings modal.
Check the chat for system messages like “Plan creation failed”. Most
common cause is one of the voter agents being unauthenticated or
unreachable. Run claude --print "test" and
gemini --prompt "test" from a terminal to confirm both are
working.
A known bug — wget defaults to IPv6 and times out on
some Mint installs. Already absorbed into cockpit_start.sh,
but if you see the symptom elsewhere:
# Force IPv4 globally for wget
echo 'inet4_only = on' >> ~/.wgetrcThe cockpit polls the bridge every 200 ms during streams, which generates a lot of access-log entries. If you don’t need them:
# Disable access logging for /cockpit/bridge.php specifically
sudo bash -c 'cat > /etc/apache2/conf-available/cockpit-quiet.conf' << 'EOF'
SetEnvIf Request_URI "/cockpit/bridge\.php" cockpit_quiet
CustomLog ${APACHE_LOG_DIR}/access.log combined env=!cockpit_quiet
EOF
sudo a2enconf cockpit-quiet
sudo systemctl reload apache2If you ever need to wipe the cockpit:
# Stop everything
~/scripts/cockpit_stop.sh 2>/dev/null
# Web root
sudo rm -rf /var/www/html/cockpit/
# Scripts
rm -rf ~/scripts/cockpit_*.sh ~/scripts/agent_loop.sh ~/scripts/crud_executor.sh ~/scripts/install_capabilities.sh
# Data (this is destructive — projects under here are gone forever)
# Keep this if you want to preserve your chats/library/snippets
rm -rf ~/scripts/cockpit_data/
# Sudoers fragment
sudo rm /etc/sudoers.d/cockpit
# Apache PHP override (optional — only do this if no other PHP apps need it)
sudo rm /etc/php/8.3/apache2/conf.d/99-cockpit.ini
sudo systemctl restart apache2The Claude / Gemini / Ollama / LocalAI installations stay — they’re
independent of the cockpit and you may want them for direct use. LocalAI's
systemd service (localai.service) also stays enabled; disable it
yourself with sudo systemctl disable --now localai if you no
longer want it running.
That’s it. If you’ve followed all 12 steps, you have a fully working AI Cockpit. The User Guide covers what to do once it’s running.
The base install above is unchanged. These extra steps enable features added later. All are optional — the cockpit runs without them, and each feature degrades gracefully (with a hint) when its tool is missing.
Capabilities that run an MCP server (e.g. the bundled
time capability) launch it via uvx, which
ships with uv (Astral’s Python tool).
# Official installer (adds ~/.local/bin to PATH)
curl -LsSf https://astral.sh/uv/install.sh | sh
# new shell, then verify:
uvx --versionuvx <server>
is cached.npx (from Node, Step 2) covers npm-based MCP servers
and needs no extra setup.The 🎤 Voice button transcodes mic audio with ffmpeg
(already installed) and transcribes it locally with whisper.cpp.
git clone https://github.com/ggerganov/whisper.cpp ~/whisper.cpp
cd ~/whisper.cpp
cmake -B build && cmake --build build -j --config Release
# Grab a model — large-v3-turbo is the best balance and fits a 4 GB GPU:
./models/download-ggml-model.sh large-v3-turbowhisper-cli) and
the largest installed ggml-*.bin. To pin
specific paths, set them in
cockpit_data/whisper_config.json (bin,
model, language).chmod -R a+rX ~/whisper.cpp.No install needed. prism.js ships in the web root
(offline, MIT). It is loaded with Prism.manual = true so it
only highlights the cockpit’s code editor, not the chat console.
Under cockpit_data/: directives_global*.md,
directives_config.json, claude_controls.json,
gemini_controls.json, whisper_config.json,
global_caps.json, help.json. All are plain
JSON/Markdown and editable in-app (the relevant panel’s edit button
opens them in the floating editor).