kaaka docs

Running in production

The basics for a help line that stays up: a token, a supervised service, backups, a health check, and release builds on the phones.

1. Set an admin token

Export KAAKA_ADMIN_TOKEN as a long random string before starting the server, and enter the same value as the dashboard token in Kaaka Call. With the token set, the dashboard, the API and the WebSocket all require it. The landing page, this wiki, /api/health and the location link pages stay public.

export KAAKA_ADMIN_TOKEN="$(openssl rand -hex 24)"

Open /admin and enter the token on the login page; a cookie remembers it in that browser until you visit /admin/logout. Opening /admin?token=<the token> works too. Ten wrong attempts from one address in ten minutes lock that address out for ten minutes.

Demo PIN

For a demo, set KAAKA_DEMO_PIN=1234 (any short code). The landing page then shows "Try the live control room with demo PIN 1234" under an Open the control room button, and the login page offers a Use demo PIN button. The PIN unlocks everything the admin token does. Without KAAKA_ADMIN_TOKEN it is the only credential, so Kaaka Call's dashboard token must be the PIN too; with both set, the phone keeps the secret token and visitors use the PIN.

Anyone who reads the landing page can see every incident, including callers' numbers and locations. Use a demo PIN only with demo data or for a short window, then unset it and restart the server.

2. Run it as a service

Linux (systemd): copy the repository to /opt/kaaka, create the venv there (python3 -m venv .venv && .venv/bin/pip install -r server/requirements.txt), put the environment in /etc/kaaka/kaaka.env (start from deploy/kaaka.env.example), create the kaaka user, then:

sudo cp deploy/kaaka.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now kaaka
journalctl -u kaaka -f

Data lives in /var/lib/kaaka. The unit restarts the server after a crash or reboot.

macOS (launchd): edit the paths and the token in deploy/com.kaaka.server.plist, then:

cp deploy/com.kaaka.server.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.kaaka.server.plist

Logs go to ~/Library/Logs/kaaka/. Keep the Mac awake and on power (caffeinate -i or the Energy settings); a sleeping laptop is a silent control room.

The server needs no terminal: without one it skips the test console automatically, and SIGTERM stops it cleanly.

3. Back up the data directory

KAAKA_DATA_DIR (or --data-dir) holds the incident history (events.jsonl), the responder registry and the last call. It contains phone numbers and locations: restrict access to it and back it up.

4. Monitor it

GET /api/health needs no token and answers:

{"ok": true, "version": "1.0.0", "uptime_seconds": 1234, "gateway_online": true}

gateway_online is false when the Kaaka number has not sent a heartbeat for 20 minutes (KAAKA_STALE_SECONDS). Point an uptime monitor at it and alert on anything but 200 with ok: true, and separately on gateway_online: false, which usually means the phone lost Wi-Fi, power or the app.

5. Public access

Put the server behind https, either a reverse proxy with a certificate or a tunnel, and set KAAKA_PUBLIC_URL so location links work from any phone. The Kaaka number only needs HTTP to port 8080, so a tunnel to that one port is enough; through a tunnel the dashboard's WebSocket is not reachable and the pages fall back to polling.

6. Install the release builds

gateway/Kaaka.apk and client/KaakaSensors.apk are release-signed, version 1.0.0. A phone that still has an earlier debug-signed build must uninstall it first: Android refuses to update an app whose signing key changed, and the uninstall clears the app's settings, so note the dashboard address and token before you do it. Later builds signed with the same key update in place.

7. Guard the signing key

Release builds read android/keystore.properties in each app (gitignored; copy keystore.properties.example). Back up the keystore it points to. If it is lost, installed apps can never be updated under the same signature and every phone would have to uninstall and reinstall.

Server settings reference

SettingPurpose
KAAKA_ADMIN_TOKENToken for the dashboard, API and WebSocket. Strongly recommended.
--public-url / KAAKA_PUBLIC_URLPublic https address; requires the token.
KAAKA_DEMO_PINPublic demo PIN shown on the landing and login pages. Demos only.
--mdns-name / KAAKA_MDNS_NAMELocal-network name (default kaaka → http://kaaka.local:8080). KAAKA_MDNS=0 turns it off.
--data-dir / KAAKA_DATA_DIRRuntime data directory. Default: server/.
--http-port (8080), --port (8765), --host (0.0.0.0)Dashboard port, WebSocket port, bind address.
--no-console / KAAKA_CONSOLE=0Turn off the terminal test console (off automatically without a terminal).
--no-notify / KAAKA_NOTIFY=0Turn off macOS notifications.
KAAKA_STALE_SECONDSSeconds without a heartbeat before the Kaaka number counts as silent. Default 1200.

Tests: cd server && python -m unittest -q. The repository's CI runs them and both web builds on every push.

Kaaka 1.0.0 · Edit this page · In immediate danger, call 112.