Port occupancy map for homelabs
Every port. One glance. Zero guesswork.
Port-Light turns your host's listen tables, Docker, and Compose files into one traffic-light grid โ so you always know which port is taken, by what, and which are free.
45 in use ยท 4 configured
live demo ยท simulated data
How it works
Three local sources. One honest map.
No agents to install, nothing leaves the machine. Port-Light reads what is already true on your host and merges it into a single grid.
Host listen tables ยท /proc, ss
TCP/UDP ports actually bound right now.
Docker API
Container names, status, images, published mappings.
Compose files
Ports that are declared โ even when the stack is stopped.
Features
Built for people who run too many stacks.
Search that suggests
Type a port number; if it's taken, nearby free ones light up.
Conflict radar
Two Compose projects claiming the same host port get flagged before they collide.
Multi-host, one screen
Pull occupancy maps from other Port-Light instances over LAN or Tailscale.
Live, not stale
SSE pushes a refresh the moment occupancy changes; local history records every transition.
Hooks & metrics
Optional webhooks on new listeners and conflicts; Prometheus aggregates when you want them.
Agent-friendly API
GET /api/ports/suggest hands your coding agent a genuinely free port โ with leases.
Speaks your theme
Fifteen palettes from Gruvbox to Kanagawa; four UI languages.
Stays on your machine
No telemetry, no accounts, no cloud. Your port map never leaves the host.
For coding agents
Your agent picks ports. They stick.
Coding agents guess ports and collide with your stacks. Port-Light exposes a tiny API โ and an MCP stdio server โ that hands out genuinely free ports, optionally reserving them with an expiring lease.
$ curl -s "http://127.0.0.1:2100/api/ports/suggest?count=2&reserve=true&ttl=3600&label=preview" { "ports": [8081, 8082], "reserved": [8081, 8082], "range": { "start": 1, "end": 9999 } }
Appearance
Fifteen palettes. Pick yours.
Click one โ the whole site re-skins, just like the app.
Quick start
Up in one minute.
services:
port-light:
image: stepaniah/port-light:v0.7.0
container_name: port-light
restart: unless-stopped
ports:
- "2100:2100"
volumes:
- /path/to/your/compose-stacks:/compose:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /proc:/host/proc:ro
- ./data:/data
environment:
COMPOSE_SCAN_DIR: /compose
mkdir -p data docker compose up -d
โ http://localhost:2100
Images for linux/amd64 and arm64, also on GHCR. Prefer version tags over latest.
A port occupancy map โ not a container manager.
Port-Light doesn't start or stop containers, tail logs, or replace Portainer. It's a LAN tool: set Basic Auth or keep it behind a reverse proxy, and never expose port 2100.