
localhost 포트에서 수신 중인 서비스를 검사하고 관리하기 위한 CLI 도구
███████╗ ██████╗ ███╗ ██╗ █████╗ ██████╗
██╔════╝██╔═══██╗████╗ ██║██╔══██╗██╔══██╗
███████╗██║ ██║██╔██╗ ██║███████║██████╔╝
╚════██║██║ ██║██║╚██╗██║██╔══██║██╔══██╗
███████║╚██████╔╝██║ ╚████║██║ ██║██║ ██║
╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝
내 컴퓨터에서 무엇이 실행되고 있는지 알아보세요.
포트가 이미 사용 중일 때마다 lsof -iTCP -sTCP:LISTEN | grep ...을 실행하고, 그 포트가 Docker 컨테이너인지 아니면 다른 작업 트리의 고아 dev 서버인지 알아내느라 1분을 더 소비하는 데 지쳤습니다. 그래서 sonar를 만들었습니다.
로컬호스트에서 수신 대기 중인 모든 항목을 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를 통해 로그 파일을 찾아 tail로 따라갑니다. 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 형식
수신 포트 간의 설정된 연결을 보여줍니다 (예: 백엔드가 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 # TCP 개방이 아닌 HTTP 200 응답을 기다림
sonar wait 5432 --http=/health # 특정 엔드포인트 확인
sonar wait 5432 -i 500ms # 사용자 지정 폴링 간격
sonar wait 5432 -q # 출력 없음, 종료 코드만 (스크립트용)
docker compose up -d 또는 백그라운드 서비스와 함께 스크립트에서 유용합니다. --http 플래그는 단순한 TCP 소켓이 아닌 실제 HTTP 200-399 응답을 기다리므로, 서비스가 실제로 준비되기 전에 연결을 수락하는 경우를 잡아냅니다. --http=/health를 사용하여 특정 엔드포인트를 확인하세요. 종료 코드: 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 바이너리로, 메뉴바에 실시간 포트 통계를 표시합니다. 설치 스크립트나 GitHub 릴리스를 통해 sonar를 설치했다면 트레이 바이너리(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