PortChecker
PortChecker lets you run port status queries for provided hostnames or IP addresses entirely on your own server.
Open-source port checking utility, honestly reviewed. Minimal surface area, one job, does it cleanly.
TL;DR
- What it is: GPL-3.0 open-source utility to check whether specific ports are open or closed on any hostname or IP address — the same thing portchecker.io does publicly, running on your own infrastructure [1].
- Who it’s for: Homelab operators, network admins, and developers who want a private, always-available port checker they can hit from scripts, internal dashboards, or a browser tab — without sending their internal hostnames to a third-party service.
- Cost savings: The public portchecker.io is already free. This isn’t a SaaS-escape play. The value is privacy, customization, and availability: your instance answers to you, not a public rate limiter, and it can reach private IP ranges your external checker can’t [1].
- Key strength: Genuinely minimal. Two Docker containers, one
docker-compose up, and it works. The REST API makes it scriptable for firewall validation and monitoring pipelines [1]. - Key weakness: 182 GitHub stars, a single maintainer, and almost no community content beyond a handful of self-hosting guides. If the maintainer stops updating it, you own the problem.
What is PortChecker
PortChecker (portchecker.io on GitHub) is an open-source API for checking port availability on specified hostnames or IP addresses. The project description frames it plainly: “Ideal for developers and network admins, it helps troubleshoot network setups, validate firewall rules, and assess potential access points.”
The architecture is intentionally lean. A static HTML frontend sits behind Nginx. A Python backend built on Litestar handles the actual port probing. The README notes the project “aims to be super simple, with low overhead and also the least amount of dependencies as possible” — and it delivers on that. No databases, no user accounts, no persistent state.
In production, the API runs under Gunicorn with uvicorn workers. In development, you get hot-reload. Both modes are covered by the included Docker Compose files. The project also ships a Prometheus /metrics endpoint and a Grafana dashboard example — a thoughtful addition for teams that want to track probe history or API response times.
The UI presents a hostname field, a port field with quick-select buttons for common ports (HTTP, HTTPS, SSH, FTP, MySQL, PostgreSQL), and a results panel. That’s the entire product. There’s nothing hidden behind a login.
Why People Choose It
The honest answer: most people don’t need to self-host a port checker. The public portchecker.io is free, requires no setup, and handles the vast majority of use cases. The people who reach for the self-hosted version are solving a specific problem: they need to check ports that the public internet can’t see.
The use case comes up constantly in homelab and networking communities. A Reddit thread from r/selfhosted — discussing how a user accidentally left Pi-hole exposed to the outside world for months without knowing it — illustrates exactly the scenario where a self-hosted port checker matters [2]. An external service only tells you what’s reachable from the internet. It can’t tell you whether your Docker containers can talk to each other, whether your internal Kubernetes service is listening, or whether your firewall rules are correctly blocking traffic on your LAN. For that, you need something running inside your network.
Three concrete reasons people deploy their own instance:
Private IP checking. By default, the self-hosted API blocks private IP ranges (the ALLOW_PRIVATE environment variable defaults to false). Flip it to true in your compose file and you can probe 192.168.x.x, 10.x.x.x, and RFC1918 ranges — something the public tool deliberately prevents [1].
API access for automation. The REST API, documented at portchecker.io/docs, is the reason developers self-host. You can script firewall validation, drop port checks into CI/CD pipelines, or build monitoring health checks that verify services are reachable without wiring up a full observability stack [1].
Availability without rate limits. Public port checkers throttle requests. Your own instance answers to your load profile and doesn’t go down during someone else’s traffic spike.
UpGuard’s 2026 roundup of open port check tools places portchecker.io in the category of lightweight free utilities useful for spot-checks and initial network troubleshooting, rather than comprehensive security scanning — a fair characterization [4].
Features
Based on the README and first-hand deployment documentation:
Core functionality:
- Check one or multiple ports against any hostname or IPv4 address [1]
- Quick-select buttons for common ports: HTTP (80), HTTPS (443), SSH (22), FTP (21), MySQL (3306), PostgreSQL (5432) [website]
- Comma-separated port list support (any port 1–65535)
- Private IP checking via
ALLOW_PRIVATE=true[README] - Default hostname prefill via
DEFAULT_HOSTenv var — useful if you want the UI to auto-populate your server’s address [README]
API:
- REST API with route documentation at
/docs[README] - All endpoints accept hostname + port parameters
- Programmatically scriptable for firewall validation, CI checks, or monitoring pipelines [1]
Observability:
- Prometheus
/metricsendpoint for API endpoint stats, response times, and status codes [README] - Hostname parameters are anonymized/grouped in metrics to avoid leaking targets [README]
- Example Grafana dashboard included in the repository [README]
Deployment:
- Production Docker Compose with Gunicorn + uvicorn workers [README]
- Development Docker Compose with hot-reload [README]
- Pre-built container images at
ghcr.io/dsgnr/portcheckerio-web:latestandghcr.io/dsgnr/portcheckerio-api:latest[1] - Standalone mode without Docker (Node/Yarn for frontend, Python/Poetry for API) [README]
What it doesn’t do:
- No port scanning ranges (you specify exact ports, not ranges)
- No persistent history or logs out of the box (Prometheus scraping covers this if you configure it)
- No authentication — whoever can reach your instance can use it
- No IPv6 support mentioned in the README
Pricing: SaaS vs Self-Hosted Math
This isn’t a SaaS-replacement story. The hosted portchecker.io has no paid tier — it’s free. There’s nothing to escape.
Self-hosted costs:
- Software license: $0 (GPL-3.0) [README]
- Compute: $0 if you deploy alongside existing services on a homelab or VPS
- Dedicated VPS if you have nothing else: ~$5/mo on Hetzner or Contabo
The GPL-3.0 license is meaningfully different from MIT — it requires derivative works to also be GPL-licensed if distributed. For personal use, homelab deployment, or internal tooling, this doesn’t matter. If you’re planning to embed this in a commercial product or SaaS you’re shipping to customers, read the license first.
The project accepts Ko-fi donations (visible on the homepage) and is affiliated with DigitalOcean’s referral program. There are no commercial licenses, enterprise tiers, or cloud-hosted paid plans to worry about.
Deployment Reality Check
The DB Tech Reviews guide [1] walks through a complete Docker Compose deployment and it’s one of the simpler self-hosted setups in the networking category. No database, no secrets management, no multi-step initialization.
What you need:
- A Linux host with Docker and docker-compose
- Two open ports (8080 for the web UI, 8000 for the API) — or a reverse proxy to consolidate under a single domain
- That’s it
Minimal production compose:
services:
web:
image: ghcr.io/dsgnr/portcheckerio-web:latest
environment:
- DEFAULT_PORT=443
ports:
- 8080:80
depends_on:
- api
api:
image: ghcr.io/dsgnr/portcheckerio-api:latest
environment:
- ALLOW_PRIVATE=false
ports:
- 8000:8000
docker-compose up -d and you’re running. The DB Tech guide confirms this works as expected on a fresh host [1].
What can go sideways:
- No authentication. If you expose this publicly (or even on a LAN you don’t fully trust), anyone can probe ports through your instance. This turns your server into a proxy for network reconnaissance. Either keep it behind a VPN, add HTTP basic auth at the reverse proxy layer, or accept the exposure profile.
- ALLOW_PRIVATE=false is the safe default. Switching it to
truefor internal checks is the main reason to self-host, but be deliberate about it — you’re allowing the API to reach your internal network. - Small project, single maintainer. 182 stars and no obvious organizational backing. The repository is active (Python 3.13, Node 25 references suggest recent maintenance), but there’s no SLA, no paid support tier, and no company behind it.
- Prometheus/Grafana is optional but worth setting up. The metrics endpoint exists; you need to wire up your own Prometheus scrape config and import the example dashboard. Not hard, but not automatic [README].
Realistic time to a working instance for someone comfortable with Docker: 10–15 minutes. For someone following a guide without prior Docker experience: 45–90 minutes including domain + reverse proxy setup.
Pros and Cons
Pros
- Minimal and fast. No database, no state, no bloat. Two containers, one command. The README promise of “low overhead and fewest dependencies” holds [1][README].
- Private IP support. Flip one env var and you can probe RFC1918 ranges that external tools can’t reach [README][1].
- REST API included. Not bolted on after the fact — the whole project is API-first with the UI as a thin wrapper. Scriptable out of the box [README].
- Prometheus metrics. Built-in observability for teams already running a Prometheus/Grafana stack [README].
- GPL-3.0. Free to self-host, modify, and run forever. No license expiration, no per-seat fees, no cloud vendor lock-in [README].
- Pre-built container images. No build step required for standard deployments — pull and run [1][README].
Cons
- No authentication. Zero access control at the application layer. You need to manage this at the network or reverse proxy level [README].
- Single maintainer, 182 stars. Low bus factor. If the project goes unmaintained, you own it — the GPL license means you can fork, but you’ll be maintaining it yourself [README].
- No port range scanning. You check specific ports, not ranges. For comprehensive scanning, you need nmap or a dedicated security tool.
- No persistent history. Past checks aren’t stored unless you layer Prometheus scraping on top [README].
- Limited community. Almost no third-party reviews, forum threads, or troubleshooting documentation beyond the official README and one DB Tech guide [1]. You’re mostly on your own if you hit an edge case.
- IPv6 not documented. The README references IPv4 throughout. IPv6 support is unclear.
Who Should Use This / Who Shouldn’t
Use PortChecker if:
- You run a homelab or VPS and regularly need to verify that services are reachable on specific ports.
- You want to check internal/private IP ranges that external tools can’t reach.
- You want a scriptable REST API for firewall validation or CI checks, without standing up a full network monitoring stack.
- You’re already running Prometheus/Grafana and want port-check metrics alongside your other observability data.
- You need an air-gapped or network-isolated port checker — one that doesn’t phone home to any external service.
Skip it (use the public portchecker.io) if:
- You only need occasional ad-hoc port checks against public-facing hosts. The free hosted version does this identically, no setup required.
- You don’t have a VPS or server already running Docker. Spinning up a $5/mo server just for a port checker is overkill.
Skip it (use nmap) if:
- You need port range scanning, OS detection, service fingerprinting, or any of the capabilities that make nmap the standard for network reconnaissance and security auditing.
- You’re doing security assessments. Nmap’s scan options are in a different category entirely.
Skip it (use Uptime Kuma) if:
- You want continuous monitoring with alerting, not just on-demand checks. Uptime Kuma has a port monitoring probe type built in and adds history, dashboards, and notifications.
Alternatives Worth Considering
- canyouseeme.org — Free, public, no setup. Checks a single port against your current IP. Use this for quick sanity checks before bothering with anything else.
- nmap — The industry standard for port scanning. Runs locally, far more capable, zero server setup. If you’re comfortable with the command line,
nmap -p 80,443,22 hostnameoften replaces the need for a web UI entirely. - Uptime Kuma — Self-hosted monitoring tool with TCP port checks as one of many probe types. If you want continuous monitoring + history + alerts rather than ad-hoc checking, Uptime Kuma does port monitoring plus everything else (HTTP uptime, cert expiry, DNS, etc.) in one deployment.
- netcat / nc —
nc -zv hostname portfrom any Linux machine. Zero overhead, works everywhere, no UI. Good enough for one-off checks in a terminal. - UpGuard’s port check tools list — For teams looking at port checking from a security/attack-surface angle, UpGuard’s 2026 roundup covers tools purpose-built for that use case [4].
Bottom Line
PortChecker is the kind of tool that does exactly one thing and doesn’t apologize for it. If you need to check whether a port is open on a hostname, it works. The self-hosted version’s value over the public site comes down to a single decision: do you need to probe private IP ranges, do you need a REST API for automation, or do you want this to run inside a network-isolated environment? If yes to any of those, the ten-minute Docker setup is worth it. If not, use the free public version and save the server resources for something else.
The GPL-3.0 license, minimal dependencies, and included Prometheus metrics make it a solid fit as a utility alongside a homelab stack. What it isn’t is a replacement for nmap, a continuous monitoring tool, or a security scanner. The 182-star project footprint is the honest indicator of its scope: small tool, specific use case, works as described.
Sources
- DB Tech Reviews — “Self-Hosting PortChecker.io with Docker: A Comprehensive Guide” (Nov 20, 2024). https://dbtechreviews.com/2024/11/20/self-hosting-portchecker-io-with-docker-a-comprehensive-guide/
- r/selfhosted — “Well, I was an idiot and left pi-hole exposed to the outside world”. https://www.reddit.com/r/selfhosted/comments/1fykl8t/well_i_was_an_idiot_and_left_pihole_exposed_to/
- UpGuard — “Top 5 Free Open Port Check Tools in 2026”. https://www.upguard.com/blog/best-open-port-scanners
Primary sources:
- GitHub repository and README: https://github.com/dsgnr/portchecker.io (182 stars, GPL-3.0 license)
- Official website and API docs: https://portchecker.io / https://portchecker.io/docs
- Container images: https://github.com/dsgnr/portchecker.io/pkgs/container/portcheckerio-web
Features
Integrations & APIs
- REST API
Related Networking & VPN Tools
View all 99 →Caddy
71KA fast, extensible web server with automatic HTTPS — zero-config TLS certificates for every site, built-in reverse proxy, and a simple Caddyfile config format.
Traefik
62KCloud-native application proxy and ingress controller that auto-discovers services and handles TLS certificates, load balancing, and routing with zero manual configuration.
Pi-hole
56KNetwork-wide ad blocking DNS server that protects every device on your network without installing anything on individual devices.
Headscale
37KAn open source, self-hosted implementation of the Tailscale control server.
AdGuard Home
33KNetwork-wide software for blocking ads and tracking. Covers all your home devices with no client-side software needed.
Nginx Proxy Manager
32KExpose your services easily and securely. Manage Nginx proxy hosts with a simple, powerful interface and free SSL via Let's Encrypt.