localhost:9000 is port 9000 on your own computer, and several unrelated tools default to it: PHP-FPM, SonarQube, the MinIO S3 API, Graylog, ClickHouse's native protocol and older Portainer installs. The first job is finding out which one you're actually talking to, because some of them don't speak HTTP at all. That's why a browser can show an empty response or a download instead of a page.
What runs on port 9000
| Tool | What 9000 is | Open in a browser? |
|---|---|---|
| PHP-FPM | FastCGI listener behind Nginx/Apache | No, FastCGI not HTTP |
| SonarQube | Web UI and API | Yes |
| MinIO | S3-compatible API (console usually 9001) | API only |
| Portainer | HTTP UI in older setups (HTTPS 9443 is the current default) | Yes |
| Graylog | Web UI and API | Yes |
| ClickHouse | Native TCP protocol (HTTP is 8123) | No |
Find the owner first:
# macOS / Linux
lsof -i :9000
docker ps --filter "publish=9000"
# Windows
netstat -ano | findstr :9000
Fix common port 9000 problems
PHP-FPM: blank page or ERR_EMPTY_RESPONSE. You opened the FastCGI port directly. Browse to the web server instead and check it forwards PHP with fastcgi_pass 127.0.0.1:9000; (or a Unix socket). A 502 Bad Gateway from Nginx means PHP-FPM isn't running or isn't listening where fastcgi_pass points. See 502 Bad Gateway.
SonarQube refuses to connect. It needs a minute or two to start, and often dies on Linux hosts because Elasticsearch needs vm.max_map_count of at least 262144. Check logs/es.log and logs/web.log, or docker logs for the container.
MinIO shows XML instead of a UI. You're on the API port. The console is on whatever --console-address says, conventionally :9001.
Portainer not on 9000. Recent Portainer versions serve HTTPS on 9443 by default, and HTTP on 9000 only if you publish it.
Xdebug not connecting. Xdebug 3 uses 9003, not 9000. If your IDE still listens on 9000, it may be competing with PHP-FPM.
Free port 9000 or move a service
kill -9 $(lsof -ti :9000) # macOS / Linux
taskkill /PID <pid> /F # Windows
Usually it's cleaner to move one service:
- PHP-FPM:
listen = 127.0.0.1:9001in the pool config (www.conf), and updatefastcgi_pass - SonarQube:
sonar.web.port=9001inconf/sonar.properties - MinIO:
minio server /data --address :9100 --console-address :9101 - Docker: change the host side only, for example
-p 9100:9000
Open localhost:9000 from another device
For HTTP services (SonarQube, Portainer, Graylog), make sure they listen on 0.0.0.0 (the default for most Docker images) and open http://YOUR-LAN-IP:9000. PHP-FPM should stay on 127.0.0.1; an exposed FastCGI port lets anyone on the network ask PHP-FPM to execute files.
Webhooks from tools on port 9000
Two of these tools send webhooks:
- SonarQube posts the quality gate result to a URL you configure under Administration, then Webhooks, after each analysis.
- MinIO sends bucket notifications (object created, deleted) to a webhook target.
To see exactly what they send, point them at a free Webhook Bin URL and read the captured request. To handle the events with code on your laptop, forward them to a local route:
relay forward --bucket sonar-events http://localhost:8000/sonar
The bucket's public URL stays the same, so you configure it in SonarQube or MinIO once, and every delivery is logged for replay. Keep the services themselves private: neither the SonarQube admin UI nor the MinIO API should be on a public URL without authentication you trust.
