PortNote
Centralized web dashboard to document, track, and auto-scan port assignments across all your servers and VMs — no more spreadsheets.
PortNote is an open-source port management tool built for system administrators and DevOps engineers who manage multiple servers and VMs. Rather than maintaining fragmented spreadsheets or relying on memory, PortNote gives teams a single searchable web interface to assign, annotate, and audit port usage across their entire infrastructure. Each port entry can be tagged with a service name and freetext note, making it easy to understand intent at a glance.
What sets PortNote apart from similar trackers is its companion Go-based agent that performs live TCP port scanning against registered servers. The agent runs as a separate Docker container, polling a shared PostgreSQL database every ten seconds for pending scan requests. When triggered from the dashboard, it uses 2,000 concurrent goroutines to probe all 65,535 TCP ports on the target IP and writes newly discovered open ports back to the database — turning passive documentation into active discovery.
The frontend is built with Next.js 15 and React 19, styled with Tailwind CSS and DaisyUI in a night-mode-first aesthetic suited for operations environments. Deployment requires only a single Docker Compose file that brings up the web server, the Go scanning agent, and a PostgreSQL 17 database with persistent volumes. Prisma ORM handles schema migrations automatically on container startup, so there is no manual database setup step.
What You Get
- Centralized Port Dashboard - Browse all registered servers and their port assignments from a single searchable interface, with collapsible server cards and visual port badges for fast scanning.
- VM Hierarchy Modeling - Register bare-metal servers and associate VMs beneath them using a parent–child relationship, with cascading deletion that cleans up all ports when a server or VM is removed.
- Port Annotation - Attach service names and freetext notes to each port entry so the purpose, owner, and service type are documented alongside the port number for team-wide clarity.
- Automated TCP Port Scanner - Trigger a full 65,535-port TCP scan of any registered server directly from the UI; the Go agent runs 2,000 concurrent goroutines and writes discovered open ports back to the database without duplicating existing entries.
- Conflict-Free Port Generator - Generate a random available port number that is not already recorded in the database, eliminating manual conflict checking when deploying new services.
- Fuzzy Search with Fuse.js - Search server names, IP addresses, and port notes with fuzzy matching so partial or misspelled queries still surface the right results.
- Sortable Server List - Sort servers and VMs alphabetically or by IP address (with proper numeric octect comparison), with sort preference persisted across sessions via cookies.
- One-Command Docker Deployment - Run the entire stack — web app, scanning agent, and PostgreSQL — with a single
docker compose upusing pre-built images from Docker Hub, with Prisma migrations applied automatically on first start.
Common Use Cases
- Preventing port collisions in multi-service deployments - A DevOps engineer registers all servers in PortNote and uses the port generator to pick guaranteed-unused ports before adding new microservices, eliminating bind failures caused by port conflicts.
- Auditing what’s actually open - A sysadmin triggers a TCP scan on a recently rebuilt VM to see every open port and compare the live state against what’s documented, identifying unexpected services without manual nmap runs.
- Onboarding engineers to legacy infrastructure - A lead engineer populates PortNote with annotated port entries for every legacy service so new team members can look up what runs on which port without reading through old runbooks or asking Slack.
- Post-incident port hygiene cleanup - After a security incident, a security engineer uses the full-port scan to discover undocumented services running on non-standard ports and documents or removes them through the dashboard.
- CI/CD test environment port allocation - A developer queries PortNote’s API to find free ports before spinning up ephemeral test containers, ensuring pipeline jobs don’t collide on shared infrastructure.
- Documentation alongside infrastructure-as-code - A platform team maintains PortNote as a living registry alongside their Terraform configs, keeping human-readable port documentation in sync with actual deployments.
Under The Hood
Architecture
PortNote is a two-process architecture: a Next.js 15 App Router web application handles the user interface and REST API surface, while a separate Go service acts as a background scanning agent. The web application’s API routes each instantiate their own PrismaClient directly, with no service layer or repository abstraction sitting between the HTTP handler and the database. The Go agent communicates with the shared PostgreSQL database through the pgxpool connection pool rather than through the web API, polling the Scan table on a ten-second ticker and writing discovered ports back in batches. This database-as-message-bus design keeps the two services decoupled without requiring an internal network API, though it also means the agent cannot be swapped without modifying database schema. The frontend Dashboard component manages all UI state — server list, form state, expanded cards, search query, and sort order — in a single large React component, with sort and expanded-card preferences persisted to cookies for session continuity.
Tech Stack
The web application is written in TypeScript with Next.js 15 and React 19, using the App Router for file-based routing and server-side API routes. Prisma 6 with PostgreSQL provides the data layer, with schema migrations applied at container startup via prisma migrate deploy. The UI uses Tailwind CSS v4 and DaisyUI 5 configured in night mode as the default theme, with Lucide React icons and Fuse.js for client-side fuzzy search. The scanning agent is a standalone Go binary using pgxpool from the jackc/pgx library for high-throughput concurrent database writes. Both services ship as Docker images built with multi-stage Node 20 Alpine Dockerfiles and a cross-platform Go build, orchestrated by Docker Compose alongside a PostgreSQL 17 container with a persistent named volume.
Code Quality
The codebase has no test files of any kind — no unit tests, no integration tests, and no testing framework configuration. Error handling in API routes catches all errors and returns them as JSON, but the error messages expose raw Prisma and Node.js internals to the client rather than mapping them to user-facing messages. The Go agent handles errors with log-and-continue patterns appropriate for a background worker. TypeScript strict mode is not explicitly enabled but type coverage is reasonable at the interface and component level, with shared type definitions in a dedicated types.ts module. There is no ESLint or Prettier configuration committed to the repository, though next lint is available as a script. Comment density is minimal throughout both the TypeScript and Go codebases. Code organization follows Next.js App Router conventions without additional domain layering.
What Makes It Unique
The most distinctive technical decision is the Go scanning agent that performs actual live TCP port discovery rather than merely tracking what humans manually enter. The agent uses a worker-pool pattern with 2,000 concurrent goroutines and a 750-millisecond dial timeout to scan all 65,535 TCP ports on a target host in seconds, deduplicating results against existing database records before batch-inserting only net-new open ports using pgx’s batch API. The Scan table functions as a lightweight job queue that decouples scan requests from execution — the frontend inserts a row, and the agent picks it up on the next ten-second tick. This database-mediated async pattern avoids inter-service HTTP calls entirely. The server data model encodes VM hierarchy using a self-referential host foreign key on the Server table, and cascading delete logic in the API ensures that removing a bare-metal host atomically removes all its VMs and every port associated with any of them.
Self-Hosting
PortNote is released under the MIT License, which grants broad freedoms: anyone may use, copy, modify, merge, publish, distribute, sublicense, and sell copies of the software without restriction, and there are no copyleft obligations that would require derivative works to be open-sourced. Commercial use is fully permitted. The only requirements are that the copyright notice and license text be included in any distribution. There are no commercial tiers, paid features, or enterprise add-ons — the entire codebase is available under this single permissive license.
Running PortNote yourself requires Docker and Docker Compose. The compose file brings up three containers: the Next.js web server on port 3000, the Go scanning agent, and PostgreSQL 17 with a persistent volume. Configuration is handled entirely through environment variables — you supply a JWT secret, a user secret, a login username and password, and the database URL. Prisma migrations run automatically when the web container starts, so initial setup is a single docker compose up. The operational burden is modest for a small team: you are responsible for PostgreSQL backups, container restarts on failure, and OS-level security on the host. There is no built-in backup tooling, no health-check endpoint, and no horizontal scaling support — this is designed for a single-node deployment.
There is no hosted or SaaS version of PortNote, so there is no managed alternative to compare against. What you give up by self-hosting is mainly operational convenience: no automatic updates, no managed database backups, no support channel beyond GitHub Issues, and no SLA. The project is maintained by a single developer and has been quiet since May 2025, so users should factor in the possibility of limited future updates when evaluating it for long-term production use.
Related Apps
RustDesk
Networking
Open-source, self-hosted remote desktop built in Rust — your data, your infrastructure, no third-party cloud.
RustDesk
AGPL 3.0frp
Networking
A fast reverse proxy that exposes local servers behind NAT or firewalls to the public internet with multi-protocol support.
frp
Apache 2.0LocalSend
Networking
An open-source, cross-platform AirDrop alternative that sends files and messages device-to-device over your local network with no internet, no account, and no cloud server involved.