kj sonar
kj sonar manages the SonarQube container Karajan uses for static analysis. SonarQube is a containerised server, not a binary, and Karajan owns its lifecycle so you never hand-write docker run for it. This is the command surface for that lifecycle.
What it does
Section titled “What it does”kj sonar <subcommand> controls the local SonarQube server (server + database containers) that kj scan, the sonar role in kj run, and the Sonar collector in kj audit all depend on. It wraps the container operations — bring up, tear down, health, logs, dashboard — behind subcommands so the rest of Karajan can just assume “Sonar is there or it isn’t”.
Subcommands: start (bring the container up), stop (tear it down), status (running? healthy?), logs (tail container logs for debugging), open (open the SonarQube web dashboard in your browser). kj init brings Sonar up for you on first setup; kj sonar is for managing it afterwards. It requires a working Docker daemon — Sonar’s hard prerequisite.
When to use
Section titled “When to use”- Sonar-dependent step failed —
kj sonar statusto check the container before blaming the pipeline. - Container needs a restart —
kj sonar stopthenkj sonar start(e.g. after the daily Anthropic-limit window where the user note in memory applies). - Inspecting findings in the UI —
kj sonar opento browse the dashboard, not just the CLI summary. - Debugging a scan —
kj sonar logswhenkj scanbehaves oddly. - Freeing resources —
kj sonar stopwhen you won’t audit/scan for a while (it’s a heavyweight container).
When NOT to use
Section titled “When NOT to use”- You just want to scan —
kj scan(it assumes Sonar is up; bring it up once withkj sonar start). - No Docker —
kj sonarcan’t manage a container without a daemon.kj install-toolsreports the Docker install hint. - First-time setup —
kj initalready brings Sonar up; you don’t needkj sonar startimmediately after. - Reasoning over findings —
kj auditfor LLM analysis;kj sonaronly manages the server.
Subcommands
Section titled “Subcommands”| Subcommand | Effect |
|---|---|
start | Bring the SonarQube container up (and its DB). Idempotent. |
stop | Tear the container down. Frees memory; scans unavailable until restarted. |
status | Report running/healthy state. The first thing to check on a Sonar failure. |
logs | Tail the container logs — for diagnosing scan/startup issues. |
open | Open the SonarQube web dashboard in the default browser. |
kj sonar subcommands take no flags — the server’s configuration (port, token) lives in karajan.config.yml, bootstrapped by kj init.
Examples
Section titled “Examples”Typical: check before blaming the pipeline
Section titled “Typical: check before blaming the pipeline”kj sonar status && kj scanWhat happens: confirms the container is up and healthy, then scans. If status is red, you know the problem is Sonar, not your code or the reviewer.
Restart after the daily limit window
Section titled “Restart after the daily limit window”kj sonar stop && kj sonar startWhat happens: a clean container cycle — the standard fix when Sonar gets into a bad state (the documented workaround for the “container being restarted” case --no-sonar exists for).
Debug a misbehaving scan
Section titled “Debug a misbehaving scan”kj sonar logsWhat happens: tails the SonarQube container logs so you can see why analysis failed (OOM, plugin error, DB connection) instead of guessing.
How it works internally
Section titled “How it works internally”kj sonar exists because Sonar is the one integration that is genuinely stateful infrastructure, not a stateless binary you invoke. OSV-Scanner and Semgrep are “run and forget”; SonarQube is a long-lived server with a database that has a lifecycle, health states, and resource cost. Pretending it’s uniform with the other tools would leak Docker management into every command that touches Sonar. Instead Karajan centralises the lifecycle here and lets kj scan / kj audit / the sonar role assume a binary world (“up or not”) — the messy container reality is contained in this one command.
The no-flags design mirrors kj scan’s reasoning: anything that changes how Sonar behaves (port, token, project key) is configuration that belongs in the versioned karajan.config.yml, set once by kj init, not in invocation-time flags that would drift per machine and make “why is Sonar different here?” unanswerable. kj sonar is deliberately just verbs on a lifecycle — start, stop, look, log, open — because that’s the entire honest surface of “manage a container someone else configured”.
Related
Section titled “Related”kj scan— the deterministic scan that needs this container up.kj audit— its Sonar collector depends on this server.kj init— brings Sonar up on first setup.kj doctor— health-checks the Sonar container among everything else.- External tools → SonarQube / Docker — what Sonar is and why Docker is its prerequisite.