███████╗ ██████╗ ███╗ ██╗ █████╗ ██████╗ ██╔════╝██╔═══██╗████╗ ██║██╔══██╗██╔══██╗ ███████╗██║ ██║██╔██╗ ██║███████║██████╔╝ ╚════██║██║ ██║██║╚██╗██║██╔══██║██╔══██╗ ███████║╚██████╔╝██║ ╚████║██║ ██║██║ ██║ ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ Know what's running on your machine.
I got tired of running lsof -iTCP -sTCP:LISTEN | grep ... every time a port was already taken, then spending another minute figuring out if it was a Docker container or some orphaned dev server from another worktree. So I built sonar.
It shows everything listening on localhost, with Docker container names, Compose projects, resource usage, and clickable URLs. You can kill processes, tail logs, shell into containers, and more — all by port number.
$ 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)
Install
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/install.sh | bash
Downloads the latest binary to ~/.local/bin and adds it to your PATH if needed. Restart your terminal or source ~/.zshrc .
Custom install location:
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash
Shell completions (tab-complete port numbers):
... continue reading