アップデート一覧に戻る
New releaseSep 4, 2026

sonar v0.4.1

localhost ポートで待受中のサービスを調査・管理するための CLI ツール

共有
██████    ███    ██████    ██    ██████
██           ██      ██  ██  ██      ██
██      ██   ██  ██  ██  ██  ██      ██
  ██  ██   ██  ██  ██  ██  ██  ████
    ██  ██       ██  ██  ██  ██  ██  ██
██████    ███    ██  ██  ██  ██  ██  ██

マシン上で何が動いているかを把握できます。

Sonar は localhost でリッスンしているすべてを表示し、整理します。すべてのポートは group に属し — 通常はそれが起動されたリポジトリです — そしてそのグループ内では名前付きの service に属します。sonar start で開発サーバーを起動すれば、プロジェクト全体が 1 つのものとなり、ツリーとして一覧表示し、待機し、tail し、単一のコマンドで停止できます。Docker コンテナ、Compose プロジェクト、手動で起動したプロセスも、設定なしで検出されます。

$ sonar list --tree
my-app  (3 ports, running)                        ~/code/my-app
├─ 5432  db          postgres:17                  http://localhost:5432
├─ 5173  frontend    vite (v5.4)                  http://localhost:5173
└─ 8000  api         uvicorn app:app              http://localhost:8000
ungrouped (1 port)
└─ 3000  next-server (v16.1.6)                    http://localhost:3000

インストール

Homebrew (macOS / Linux)

brew install raskrebs/sonar/sonar

Homebrew 6 は、一度タップを信頼するまでサードパーティのタップからの formulae を拒否します (Error: Refusing to load formula raskrebs/sonar/sonar from untrusted tap):

brew trust raskrebs/sonar

インストールスクリプト

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | bash

最新のバイナリを ~/.local/bin にダウンロードし、必要に応じて PATH に追加します。ターミナルを再起動するか、source ~/.zshrc を実行してください。

Windows の場合 (PowerShell):

irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex

カスタムインストール場所:

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash

特定のバージョンをインストールする:

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_VERSION=vX.Y.Z bash
$env:SONAR_VERSION="vX.Y.Z"; irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex

Go の使用

go install github.com/raskrebs/sonar@latest

シェル補完(ポート番号のタブ補完):

sonar completion zsh > "${fpath[1]}/_sonar"   # zsh
sonar completion bash > /etc/bash_completion.d/sonar  # bash
sonar completion fish | source                 # fish

60秒

リポジトリのルートに sonar.yaml を置いて、dev.sh の代わりにプロジェクトの実行方法を記述します:

name: my-app
services:
  - name: db
    cmd: docker compose up db
    port: 5432
  - name: api
    cmd: uv run uvicorn app:app --port ${port}
    port: auto
    depends_on: [db]
  - name: frontend
    cmd: npm run dev -- --port ${port} --strictPort
    port: auto
    depends_on: [api]
    env:
      VITE_API_URL: ${api.url}

Then start it:

sonar start
  ✓ db        http://localhost:5432   pid 41022  ~/.config/sonar/logs/my-app/db.log
  ✓ api       http://localhost:21408  pid 41040  ~/.config/sonar/logs/my-app/api.log
  ✓ frontend  http://localhost:21409  pid 41077  ~/.config/sonar/logs/my-app/frontend.log

3 started
following the logs; Ctrl+C stops the 3 services started here
api      | INFO:     Uvicorn running on http://127.0.0.1:21408
frontend | VITE v5.4  ready in 312 ms

Sonar は port: auto の各サービスに空きポートを割り当て、各サービスに他のサービスの場所を伝えるため、2 つ目の worktree が最初のものと並行して動作し、ポートが衝突することはありません。sonar start -d は同じことをバックグラウンドで実行し、sonar down はそれを停止してポートを解放します。別のターミナルで:

sonar list --tree
my-app  (3 ports, running)                        ~/code/my-app
├─ 5432   db          postgres:17                 http://localhost:5432
├─ 21408  api         uvicorn app:app             http://localhost:21408
└─ 21409  frontend    vite (v5.4)                 http://localhost:21409

sonar.yaml がない場合、sonar start -- npm run dev は1つのコマンドを名前付きサービスとして実行し、sonar list と sonar kill はリッスンしているものすべてに対して機能します。

以下で # check と記された例は、CI 実行のたびに scripts/readme-check.sh によって新規ビルドに対して実行されます。

コマンド

sonar list

sonar list
sonar list --tree
sonar list --group my-app
sonar list --json
# check
sonar list --stats             # CPU, memory, threads, uptime, state
sonar list --health            # HTTP health checks
sonar list --filter docker     # only Docker ports
sonar list --sort name         # port | pid | name | type
sonar list -a                  # include desktop apps
sonar list -c port,process,group,cpu,mem
sonar list --host user@server  # scan a remote machine over SSH

デフォルトのカラムは port、process、group、container、image、 containerport、url です。ここで process はあなたがポートに付けた名前 (sonar rename) を表示し、次にサービス名、そして検出された内容を表示します。

利用可能なカラム: port、process、pid、type、url、group、cpu、 mem、threads、uptime、state、connections、health、latency、 container、image、containerport、compose、project、user、bind、 ip。

たまたまリッスンしているデスクトップアプリやシステムサービス — Figma、Discord、 Spotify、ControlCenter、macOS の .app バンドル、/System/Library/ のデーモン — は -a を渡さない限り非表示になります。

sonar start

sonar.yaml からプロジェクトを開始します:

sonar start                    # every service in the nearest sonar.yaml
sonar start api frontend       # only these (they still wait for their dependencies)
sonar start ../other-project   # the sonar.yaml in or above another directory
sonar start -d                 # in the background, like `sonar up`

フォアグラウンドでは、sonar はデーモンを介してサービスを起動し、各行の先頭にサービス名を付けてログを追跡し、Ctrl+C を押すと起動したサービスを停止します。すでに実行中のサービスはそのままにされ、sonar が起動したすべてのサービスが終了すると、sonar は自動的に終了します。

-- より前の引数はディレクトリまたはサービスを指定し、-- より後のすべてはコマンドです。または、グループ内の名前付きサービスとして 1 つのコマンドを実行します:

sonar start -- npm run dev
sonar start --group my-app --name frontend -- npm run dev
sonar start --port 5173 -- npm run dev        # expected port, before it binds
sonar start --detach --name api -- uv run uvicorn app:app
sonar start --list

何も渡す必要はない:

  • Group — --group、なければ最も近い sonar.yaml の name、なければ git ルートのディレクトリ名(worktree の場合は repo@worktree になる)、なければ カレントディレクトリの名前。
  • Name — --name、なければ cmd が一致する sonar.yaml のサービス、なければ コマンドから推測される(npm run dev → dev、uv run api → api、 python -m uvicorn → uvicorn、./dev.sh → dev.sh)。
  • Port — --port はヒントであり、バインディングではない:ポートが実際に リッスンするまで実行は starting として表示され、デーモンはそれを使って プロセスをポートに照合する。

子プロセスは stdin、stdout、stderr、cwd、環境を継承し、さらに SONAR_GROUP、SONAR_NAME、SONAR_RUN_ID も継承する。子プロセスは独自の プロセスグループを取得するため、sonar kill はツリー全体 — ウォッチャーや ワーカーを伴う開発サーバー — を停止する。Ctrl+C は転送され、sonar は子プロセスの 終了コードで終了する。

--detach は即座に戻り、出力を ~/.config/sonar/logs/<group>/<name>.log に書き込む。--list は sonar が起動した ものと、その下にその後終了したもの — 終了コード、およびクラッシュしたのか 停止されたのか — を表示する(機械可読形式には --json):

sonar start --list
sonar start --detach --name demo --port 8123 -- sleep 5
sonar start --list --json
# check

sonar.yaml

プロジェクトはリポジトリのルートにある sonar.yaml で自身とそのサービスに名前を付けます。これは任意です — これがなくても sonar は git ルートでグループ化します — そしてコミットされることを意図しています:

name: my-app
services:
  - name: db
    cmd: docker compose up db
    port: 5432
    health: /
    description: Postgres 17
    icon: database
    color: "#4f8cc9"
  - name: api
    cmd: uv run uvicorn app:app --port 8000
    cwd: backend
    port: 8000
    health: /healthz
    depends_on: [db]
  - name: frontend
    cmd: npm run dev
    port: 5173
    depends_on: [api]
ports: [9229]        # ports that belong to this project without a service
  • name — グループ名。スラッシュや空白は使用できません。
  • cmd、cwd、port — sonar start がサービスを起動する方法。cwd は ファイルからの相対パスで、そのディレクトリの外に出ることはできません。
  • health — サービスが起動している間、デーモンがポーリングする HTTP パス。 これにより、サービスが実行中でもまだ正常でない場合があります。ok、fail、 unknown を報告し、失敗の理由も示します。
  • description、icon、color — デスクトップアプリ用の自由形式のメタデータ。sonar がこれらを推測することはありません。
  • depends_on — 起動順序。ファイルに存在しないサービスを指定したり、 循環を指定するとエラーになります。無効なファイルは一度報告され、スキャンを停止させることはありません。
  • env — sonar がサービスを起動するときに設定される変数。

port: auto と参照

サービスはポートを sonar に任せることができ、ハードコードされた localhost:8080 の代わりに 環境変数を通じて他のサービスを見つけることができます:

カテゴリ