portracker: a self-hosted port map that reads the host, not a config file
An open source, self-hosted, real-time port monitoring and discovery tool.
At a glance
- What is it?
- portracker is an MIT-licensed Node.js service that scans the host it runs on and builds a live inventory of listening ports, with Docker and TrueNAS collectors layered on top. It is a good fit for a single admin running containers at home or on a small NAS, and a poor fit for anyone who wants a scheduled, agent-based audit.
- Who is it for?
- Adopt portracker if you run a handful of Docker hosts or a TrueNAS box and you are tired of maintaining a spreadsheet of which service sits on which port. Skip it if you need historical port data, alerting, or anything that works without host-level privileges, because the design is a live view backed by a local SQLite file and nothing else.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The spreadsheet problem portracker is aimed at
Anyone running more than a couple of containers eventually keeps a note somewhere listing which service answers on which port. That note goes stale the moment a compose file changes, and the failure mode is a new container that will not bind because something else already holds the port. portracker's stated goal is to remove that manual tracking step: the README says it "helps eliminate manual tracking in spreadsheets and prevents deployment failures caused by port conflicts." The audience is narrow and specific. It is the self-hosting crowd, the repository topics name truenas explicitly, and the deployment instructions assume you have Docker and are comfortable granting a container host-level access. It is not aimed at teams that need a change log of port state over time, and it is not aimed at cloud environments where you do not control the host kernel.
How the scanner sees your ports
The mechanism is host introspection rather than configuration parsing. portracker runs with pid: "host", which puts the container in the host PID namespace, and the compose file grants SYS_PTRACE so the process can read other PIDs' /proc entries, plus SYS_ADMIN and an unconfined AppArmor profile for namespace access. From those /proc entries it derives the listening sockets and the processes behind them. This is why the setup is not negotiable: drop pid: host or the capabilities and the system ports view has nothing to read. On top of that base scan sit platform collectors. A Docker collector reads the Docker API, either through a mounted /var/run/docker.sock or through DOCKER_HOST pointing at a proxy, and the README notes it distinguishes internal container ports from published host ports. A TrueNAS collector activates only when TRUENAS_API_KEY is set, and it adds VM discovery plus system details such as OS version and uptime. VMs found that way appear read-only; the README instructs you to deploy a portracker instance inside each VM and add it as a separate server for full monitoring. Results are cached, with CACHE_TIMEOUT_MS defaulting to 60000 milliseconds, and everything lands in an embedded SQLite database at /data/portracker.db. There is no PostgreSQL or Redis dependency, which is the trade-off that keeps the install to one container.
Getting it running with Docker Compose
The README's quick start is a single compose service. The image is mostafawahied/portracker:latest, the container is named portracker, restart is unless-stopped, and the port mapping is 4999:4999. Three settings carry the actual function: pid: "host", cap_add with SYS_PTRACE and SYS_ADMIN, and security_opt with apparmor:unconfined. Two volumes are required, ./portracker-data:/data for persistence and /var/run/docker.sock:/var/run/docker.sock:ro for Docker discovery. The optional TRUENAS_API_KEY environment variable is commented out in the sample. A docker run command with the same flags is given as an alternative. If you would rather not hand the container the Docker socket, the README documents a second compose file that runs tecnativa/docker-socket-proxy with CONTAINERS=1, IMAGES=1, INFO=1, NETWORKS=1 and POST=0, and points portracker at it with DOCKER_HOST=tcp://docker-proxy:2375. Note what that proxy does and does not change: it restricts the Docker API to read-only calls, but the portracker service still needs pid: host, SYS_PTRACE, SYS_ADMIN and the unconfined AppArmor profile. The proxy removes one mount, not the privileged posture. Configuration beyond that is a short environment table: PORT (default 4999), DATABASE_PATH (default /data/portracker.db), ENABLE_AUTH (default false, added in v1.2.0), SESSION_SECRET, which the README says prevents logout on container restart when auth is on, and CACHE_TIMEOUT_MS. The table in the supplied README is truncated mid-row at DISAB, so there is at least one further variable I cannot describe.
Peers and grouping are the part that scales past one box
A single instance only knows its own host. The feature that extends the view is peer monitoring: you add other portracker instances and see their servers, containers and VMs in one dashboard. Hierarchical grouping lets you nest those peers in a parent-child structure, and the README's example is a VM's instance filed under its physical host. That maps well onto a small estate of one hypervisor plus a few guests, and it avoids the read-only limitation of TrueNAS VM discovery, since each guest runs its own scanner. The cost is that every peer is another container with the same host-level permissions on its machine, plus a network path between them. The README does not describe how peer authentication works, and ENABLE_AUTH defaults to false, so the trust model between instances is something you have to reason about yourself before exposing any of them beyond localhost.
Where portracker is the wrong tool
The design is a live view, and that is a real boundary. There is no history in the described model: the SQLite file holds state, scans are cached for CACHE_TIMEOUT_MS, and nothing in the README describes retention, diffing, or alerting on a port appearing or disappearing. If your question is "what changed on this host last Tuesday", portracker does not answer it. The privileges are the second boundary. pid: host, SYS_PTRACE, SYS_ADMIN and apparmor:unconfined together mean the container can inspect other processes on the machine; on a shared or hardened host, that is a policy conversation, not a checkbox. The README also flags the MacOS case: SYS_ADMIN is listed as required for host port namespace access on Docker Desktop. Third, TrueNAS VM discovery is read-only by design, so a TrueNAS-only deployment gives you a partial inventory until you install an instance on each guest. And the project is young: the release list shows three patch releases on the same day, 2026-05-05, which suggests a fast fix cadence rather than a settled API. Nothing in the material tells you how stable the peer or grouping data model is across upgrades.
What it is not: a scheduled audit or a network scanner
The obvious alternative is not another self-hosted dashboard but the tools already on the host. nmap answers "what is listening on this address" from outside the machine, with no container privileges at all, and it can be run on a schedule and its output diffed between runs. The difference in approach matters: nmap probes the network and sees what is reachable, so it will miss a service bound to 127.0.0.1, and it cannot tell you which process owns a port or which container published it. portracker reads /proc and the Docker API, so it knows the process and the container context, but it only sees the host it runs on and it holds no history. If you want a periodic report of open ports across many machines, a scheduled nmap run plus a diff is simpler and needs no elevated container. If you want to know which container is squatting on 8080 right now, and to see that alongside the host's own services, portracker is doing work nmap cannot do. The two are complements, not substitutes, and the README does not claim otherwise.
Licence, upgrades and what maintenance actually costs
The project is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive licence, and it means the practical constraint is not legal but operational: you are running a container with host PID namespace access and SYS_PTRACE, so your patch cadence is a security decision, not just a feature decision. The image tag in the README is latest, which will pull whatever was pushed most recently; pinning to a version tag is the safer default for anything you leave running. Upgrading means pulling a new image and recreating the container, and the only state to preserve is the /data volume holding portracker.db, since there is no external database to migrate. The release history shows v1.3.10, v1.3.9 and v1.3.8 all dated 2026-05-05, so expect frequent small releases; the README does not document a migration path or a schema version, so back up /data before you move tags. I am not giving legal advice here, and if the MIT terms matter to your organisation, read the LICENSE file in the repository rather than this summary.
Editorial conclusion
Adopt portracker if you run a handful of Docker hosts or a TrueNAS box and you are tired of maintaining a spreadsheet of which service sits on which port. Skip it if you need historical port data, alerting, or anything that works without host-level privileges, because the design is a live view backed by a local SQLite file and nothing else. Before you commit, verify two things on your own machine: that the container starts with pid: host and the SYS_PTRACE and SYS_ADMIN capabilities on your kernel, and that /data/portracker.db persists across a restart so your peer list and grouping survive. If you cannot grant those capabilities, the Docker socket proxy path in the README only removes the socket mount, not the privileged host access the scanner needs.
Community notes