Gateway service
このコンテンツはまだ日本語訳がありません。
kurahi service is the one supported way to run a Gateway in the background. It hands the
process to the operating system’s service manager, which starts it at login (or boot),
restarts it when it exits and reports its real state:
| OS | Manager | Definition |
|---|---|---|
| Linux | systemd --user |
~/.config/systemd/user/kolo-gateway@<id>.service |
| macOS | launchd (LaunchAgent) | ~/Library/LaunchAgents/com.kodasoken.kolo.<id>.plist |
| Windows | Task Scheduler + runner | task \KoLo\gateway-<id>, action <state root>\service\gateway.cmd |
The Gateway exits on fatal errors on purpose. The service manager brings it back
(systemd Restart=always, RestartSec=3; launchd KeepAlive; the Windows runner restarts
after 3 s).
Commands
Section titled “Commands”kurahi service install [--id <identity>] [--port <port>] [--home <dir>] [--no-start]kurahi service start [--id <identity>]kurahi service stop [--id <identity>]kurahi service restart [--id <identity>]kurahi service status [--id <identity>] [--no-probe] [--json]kurahi service logs [--id <identity>] [-n <lines>] [--max-bytes <n>]kurahi service uninstall [--id <identity>]installwrites the definition, enables it and starts it (unless--no-start). It is safe to run again: it rewrites the definition and restarts the service.statusasks the service manager (systemctl --user show,launchctl print,schtasks /Query) for the process state, pid and restart count, then probesGET /healthon the identity’s port. It exits with code 3 when the service is not installed.logsreads the OS log:journalctl --user -u kolo-gateway@<id>.serviceon Linux, thelogs/gateway.out.logandlogs/gateway.err.logfiles named in the plist on macOS, and the runner’slogs/gateway.logon Windows. Output is capped (64 KB by default).uninstallstops and removes the definition. The state root is kept.
Identities, state roots and ports
Section titled “Identities, state roots and ports”Each identity is its own service with its own state root and port, so several gateways can run side by side without sharing locks, sessions or credentials.
| Identity | State root (KOLO_HOME) |
|---|---|
default |
$KOLO_HOME if set, otherwise ~/.kolo (Windows: %LOCALAPPDATA%\KoLo) |
any other <id> |
the default root plus -<id>: ~/.kolo-<id> (Windows: %LOCALAPPDATA%\KoLo-<id>) |
--home <dir> |
<dir> (overrides both) |
Ids are 1 to 32 characters of a-z, 0-9, - and _.
The port comes from --port, then from the last install (<state root>/service/service.json),
then from gateway.port in <state root>/kolo.json, then 18789.
Pick any free port per identity; nothing in Kurahi reserves a fixed set. Check that a port is unused before installing.
Example: two identities on one host (<port-a> and <port-b> are ports you choose).
kurahi service install --id alpha --port <port-a>kurahi service install --id beta --port <port-b>kurahi service status --id betaSecrets: the env file
Section titled “Secrets: the env file”Secrets never go into the unit, plist, task, kolo.json or command line. Put them in
<state root>/env (created by install with mode 0600 if missing):
# <state root>/envKOLO_GATEWAY_TOKEN=...systemd reads it with EnvironmentFile=; on macOS and Windows the runner
(dist/daemon/supervisor/runner.js) loads it before it starts the Gateway. Restart the
service after editing it.
Platform notes
Section titled “Platform notes”- Needs a systemd user session. On WSL2 enable systemd in
/etc/wsl.conf([boot]systemd=true). - Without lingering the Gateway stops when you log out.
installtells you when lingering is off; enable it withloginctl enable-linger. KillMode=mixed:stopsendsSIGTERMto the Gateway andSIGKILLto anything left in its cgroup after 15 s.
- The job runs in the
gui/<uid>domain.stopuseslaunchctl bootout(a plain kill would be undone byKeepAlive);startbootstraps it again.
Windows (native)
Section titled “Windows (native)”- The task triggers at logon and runs as the current user without a stored password
(
/RU <user> /IT). If Task Scheduler denies the create, run the install once from an elevated PowerShell. stopends the runner and the Gateway using the pids the runner records in<state root>\run\gateway.pid, then ends the task. No process name matching is involved.
Freeing a busy port (--force)
Section titled “Freeing a busy port (--force)”kurahi gateway run --force no longer needs lsof or fuser. It probes the port with Node’s
net module and only signals the pid named in the identity’s gateway lock
(<state root>/run/gateway.lock, or the legacy lock in the temp dir). On Linux it also checks
/proc that the pid owns the listening socket. A port held by any other process is reported
and left alone.
PM2 (deprecated)
Section titled “PM2 (deprecated)”A PM2 ecosystem.config.cjs may still exist on older hosts, but PM2 is no longer the supported
supervisor. kurahi service install, start, restart and status print a notice when they
see PM2 managing a gateway (they read PM2’s pid files under $PM2_HOME/pids; they never run
or signal PM2).
Migrating one identity:
- Note its state root and port from the PM2 app definition.
- Copy any secret environment variables into
<state root>/env. - Stop the PM2 app (
pm2 stop <app>andpm2 delete <app>, thenpm2 save). kurahi service install --id <id> --home <state root> --port <port>.kurahi service status --id <id>showsrunningandhealth: ok.
Legacy commands
Section titled “Legacy commands”kurahi gateway install|start|stop|restart|status and kurahi daemon ... still manage the older
single-profile service (kolo-gateway.service, ai.kolo.gateway, task “KoLo Gateway”). They print
a pointer to kurahi service. Do not run both for the same state root and port.
Smoke test
Section titled “Smoke test”From a source checkout, after pnpm build:
pnpm smokeIt creates a fresh ~/.kolo-test, starts the Gateway from dist/ on the first free port in
18860 to 18899 (or --port / KOLO_SMOKE_PORT), waits for /health, checks readiness, runs
the WebSocket connect handshake, stops the Gateway with SIGTERM (then SIGKILL after 10 s)
and prints one SMOKE PASS or SMOKE FAIL line.