Install.

Works on a fresh Raspberry Pi OS Lite (64-bit), Debian 12, or any Ubuntu 22.04+ host. Log in over SSH or with a monitor + keyboard and run:

Install on a Pibash
$curl -fsSL https://sudo.abhishekslab.xyz/install.sh | bash

What the installer does

  1. Installs Docker Engine + the compose plugin if missing.
  2. Detects your architecture (arm64/amd64) and downloads the matching Sudo image tarball from sudo.abhishekslab.xyz.
  3. docker loads the image, creates the sudo-data volume, and runs the container with --restart unless-stopped.
  4. Installs a thin sudo.service systemd unit so the container is back up after any reboot or docker stop.
  5. Prints URLs for HA, the settings UI, and noVNC.

Everything else — HA onboarding, MCP setup, wake word, STT, TTS — is baked into the image and starts on first boot. The voice loop is listening for the wake word as soon as Wyoming services come up (~20 s). Inference itself runs off-device against your hosted LLM provider (OpenRouter / Anthropic / OpenAI), so there’s no model download.

Prerequisites

  • A USB or HAT microphone + any speaker. /dev/snd must exist on the host; headless server Ubuntu and Pi OS Lite are the supported configs.
  • ~5 GB free disk and ~2 GB RAM headroom on the host.
  • Outbound HTTPS — no inbound ports required.

Providing an API key

Sudo needs a hosted LLM key to answer turns. The default provider is OpenRouter (one key, hundreds of models — Claude, GPT, Llama, Gemini, free tiers). To pre-seed it at install time:

bash
OPENROUTER_API_KEY=sk-or-... \
  bash -c "$(curl -fsSL https://sudo.abhishekslab.xyz/install.sh)"

For direct Claude (the only path that controls Home Assistant devices), pass an Anthropic key instead:

bash
ANTHROPIC_API_KEY=sk-ant-... \
  bash -c "$(curl -fsSL https://sudo.abhishekslab.xyz/install.sh)"

…or skip the env var and paste any key later in the settings UI at http://<host>:3000/settings/models.

Opening the UI

bash
http://<host-ip>:8123   # Home Assistant
http://<host-ip>:3000   # Settings UI
http://127.0.0.1:6080/vnc.html   # noVNC (password below)

Retrieve the VNC password (randomized on first boot unless you set VNC_PASSWORD):

bash
sudo docker exec sudo cat /data/config/vnc_password.txt

Self-hosting the installer

For an air-gapped office or your own network, serve install.sh and the two per-arch image tarballs from Caddy:

1. Caddyfile

caddy
sudo.abhishekslab.xyz {
    root * /var/www/sudo
    file_server
    encode zstd gzip

    @script path /install.sh
    header @script Content-Type "text/x-shellscript; charset=utf-8"
}

2. Build + upload the image tarballs

bash
# From the Sudo repo root on your dev machine:
./web/scripts/image-tarball.sh all

scp install.sh root@your.host:/var/www/sudo/install.sh
scp /tmp/sudo-image-arm64.tar.gz root@your.host:/var/www/sudo/
scp /tmp/sudo-image-amd64.tar.gz root@your.host:/var/www/sudo/

3. Install from your own host

bash
SUDO_IMAGE_BASE=https://sudo.abhishekslab.xyz \
  curl -fsSL https://sudo.abhishekslab.xyz/install.sh | bash

Install from a local tarball

Already have an image tarball on the host?

bash
sudo docker load -i sudo-image-arm64.tar.gz
sudo docker tag sudo:latest-arm64 sudo:latest
SUDO_IMAGE=sudo:latest bash install.sh

Uninstall

bash
sudo systemctl disable --now sudo.service
sudo rm /etc/systemd/system/sudo.service
sudo docker rm -f sudo
sudo docker volume rm sudo-data   # warning: wipes HA config + models
sudo docker image prune -a        # optional: reclaim disk