
Инструмент командной строки для проверки и управления службами, прослушивающими порты localhost
███████╗ ██████╗ ███╗ ██╗ █████╗ ██████╗
██╔════╝██╔═══██╗████╗ ██║██╔══██╗██╔══██╗
███████╗██║ ██║██╔██╗ ██║███████║██████╔╝
╚════██║██║ ██║██║╚██╗██║██╔══██║██╔══██╗
███████║╚██████╔╝██║ ╚████║██║ ██║██║ ██║
╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝
Знайте, что работает на вашей машине.
Мне надоело каждый раз запускать lsof -iTCP -sTCP:LISTEN | grep ..., когда порт уже занят, а потом тратить ещё минуту, выясняя, это контейнер Docker или осиротевший dev-сервер из другой рабочей копии. Поэтому я написал sonar.
Он показывает всё, что слушает localhost, с именами контейнеров Docker, проектами Compose, использованием ресурсов и кликабельными URL. Вы можете убивать процессы, просматривать логи, заходить в контейнеры и многое другое — всё по номеру порта.
$ sonar list
PORT PROCESS CONTAINER IMAGE CPORT URL
1780 proxy (traefik:3.0) my-app-proxy-1 traefik:3.0 80 http://localhost:1780
3000 next-server (v16.1.6) http://localhost:3000
5432 db (postgres:17) my-app-db-1 postgres:17 5432 http://localhost:5432
6873 frontend (frontend:latest) my-app-frontend-1 frontend:latest 5173 http://localhost:6873
9700 backend (backend:latest) my-app-backend-1 backend:latest 8000 http://localhost:9700
5 ports (4 docker, 1 user)
brew install raskrebs/sonar/sonar
На macOS это также устанавливает приложение в строке меню sonar-tray.
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 install github.com/raskrebs/sonar@latest
Примечание:
go installустанавливает только CLI. Приложение в строке меню (sonar tray) — нативный бинарник Swift, его нужно собирать отдельно — см. раздел Приложение в строке меню.
Автодополнение оболочки (табуляция для номеров портов):
sonar completion zsh > "${fpath[1]}/_sonar" # zsh
sonar completion bash > /etc/bash_completion.d/sonar # bash
sonar completion fish | source # fish
sonar list # показать все порты
sonar list --stats # добавить CPU, память, состояние, время работы
sonar list --filter docker # только Docker порты
sonar list --sort name # сортировка по имени процесса
sonar list --json # вывод в JSON
sonar list -a # включая приложения рабочего стола
sonar list -c port,cpu,mem,uptime,state # пользовательские колонки
sonar list --health # выполнить HTTP-проверки работоспособности
sonar list --host user@server # сканировать удалённую машину по SSH
По умолчанию sonar скрывает приложения рабочего стола и системные службы, которые слушают TCP порты, но не имеют отношения к разработке — такие как Figma, Discord, Spotify, ControlCenter, AirPlay и другие macOS .app-пакеты и демоны из /System/Library/. Используйте -a, чтобы включить их.
Доступные колонки: port, process, pid, type, url, cpu, mem, threads, uptime, state, connections, health, latency, container, image, containerport, , , , ,
sonar info 3000
Показывает всё о порте: полную команду, пользователя, адрес привязки, CPU/память/потоки, время работы, результат проверки здоровья и, если применимо, детали Docker.
sonar kill 3000 # SIGTERM
sonar kill 3000 -f # SIGKILL
sonar kill-all --filter docker # остановить все контейнеры Docker
sonar kill-all --project my-app # остановить проект Compose
sonar kill-all --filter user -y # без подтверждения
Контейнеры Docker останавливаются командой docker stop вместо отправки сигналов.
sonar logs 3000
Для контейнеров Docker запускает docker logs -f. Для нативных процессов находит файлы логов через lsof и выводит их. На macOS использует log stream, на Linux — /proc/<pid>/fd.
sonar attach 3000 # зайти в контейнер Docker или TCP-соединение
sonar attach 3000 --shell bash # указать конкретную оболочку
sonar watch # опрос каждые 2 секунды, показывать изменения
sonar watch --stats # ресурсы в реальном времени (как docker stats)
sonar watch -i 500ms # более частый опрос
sonar watch --notify # уведомления на рабочем столе при появлении/исчезновении портов
sonar watch --host user@server # следить за удалённой машиной
sonar graph # показать, какие сервисы общаются друг с другом
sonar graph --json # структурированный вывод
sonar graph --dot # формат Graphviz DOT
Показывает установленные соединения между слушающими портами (например, ваш backend, подключающийся к postgres).
Сохраните набор ожидаемых портов для проекта, затем проверьте, что все запущены, или остановите их:
sonar profile create my-app # снимок текущих портов
sonar profile list # список сохранённых профилей
sonar profile show my-app # детали профиля
sonar up my-app # проверить, какие ожидаемые порты работают
sonar down my-app # остановить все порты из профиля
sonar wait 5432 # блокировать, пока порт не начнёт принимать соединения
sonar wait 5432 3000 6379 # ждать нескольких портов
sonar wait 5432 --timeout 30s # завершиться с ошибкой через 30 секунд
sonar wait 5432 --http # ждать HTTP 200, а не просто открытого TCP
sonar wait 5432 --http=/health # проверить конкретный endpoint
sonar wait 5432 -i 500ms # свой интервал опроса
sonar wait 5432 -q # без вывода, только код возврата (для скриптов)
Полезно для скриптов после docker compose up -d или фоновых сервисов. Флаг --http ожидает реального HTTP-ответа 200-399, а не просто TCP-сокета, что ловит сервисы, принимающие соединения до полной готовности. Используйте --http=/health, чтобы проверить конкретный endpoint. Коды возврата: 0 (готов), 1 (таймаут), 2 (прервано).
docker compose up -d
sonar wait 5432 3000 --timeout 60s && npm run migrate && npm run test
sonar map 6873 3002
Проксирует трафик так, что сервис на порту 6873 также доступен на порту 3002.
sonar next # первый свободный порт начиная с 3000
sonar next 8000 # первый свободный порт начиная с 8000
sonar next 3000-3100 # первый свободный порт в диапазоне
sonar next -n 3 # 3 последовательных свободных порта
sonar next --json # вывод в JSON
sonar open 3000 # открыть в браузере
sonar tray # приложение в строке меню с живыми данными (macOS)
sonar --no-color # отключить цвета (также учитывает переменную NO_COLOR)
Флаг --stats получает использование ресурсов для каждого процесса и контейнера. Для контейнеров Docker используется Docker Engine API для точных метрик. Без --stats sonar возвращается мгновенно.
sonar читает необязательные настройки по умолчанию из ~/.config/sonar/config.yaml. Файл
необязателен — без него применяются встроенные значения. Флаги командной строки всегда
переопределяют конфигурационный файл.
Создать начальный файл:
sonar config init # записать шаблон с комментариями
sonar config path # показать путь к файлу
sonar config edit # открыть в $EDITOR
Пример конфигурации:
list:
columns: [port, process, container, image, containerport, url]
sort: port # port | pid | name | type
filter: "" # docker | user | system | "" (все)
all: false # включать приложения рабочего стола по умолчанию
color: true # установите false, чтобы отключить цветной вывод
services: # пометить пользовательские/неизвестные порты
9000: php-fpm
5050: my-dashboard
Некорректные значения игнорируются с предупреждением; sonar продолжает работу со значениями по умолчанию.
Приложение в строке меню (только macOS) — это нативный бинарник Swift, который показывает живую статистику портов в строке меню. Если вы установили sonar через установочный скрипт или релиз на GitHub, бинарник sonar-tray включается автоматически.
Если вы установили через go install, соберите его вручную:
swiftc -O -o sonar-tray tray/SonarTray.swift -target arm64-apple-macos13
Затем переместите sonar-tray куда-нибудь в $PATH и выполните:
sonar tray
lsof)ss)netstat)Спасибо всем, кто внёс вклад в sonar!
composeprojectuserbindip