CLI tool
amalshaji/portr avatar
amalshaji/portr

Portr: a self-hosted SSH tunnel server with a local request inspector

Expose local http, tcp or websocket connections to the public internet

3,186 stars115 forksGoAGPL-3.0

At a glance

What is it?
Portr exposes local HTTP, TCP and WebSocket services on public URLs using SSH remote port forwarding, and it ships a local inspector plus a SQLite-backed log CLI. It targets small teams exposing development servers, and the README explicitly says it is not recommended alongside production servers.
Who is it for?
Adopt Portr if you run a small team that needs public URLs for development servers and you are willing to operate the server side yourself, since the README points at a separate server setup guide rather than a hosted service. Do not adopt it for production traffic: the README states plainly that it is not recommended for use alongside production servers.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Go, 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 problem Portr solves for small development teams

A local development server listens on something like port 9000 and is reachable only from the machine running it. Webhooks from a payment provider, a callback from an OAuth provider, or a colleague's browser cannot reach that port. Portr's answer is a public URL that forwards to the local service, built on SSH remote port forwarding rather than a proprietary protocol. The README frames the audience narrowly: it is primarily designed for small teams looking to expose development servers on a public URL, and it is not recommended for use alongside production servers. That second sentence is the most important line in the repository, and it should shape how you read everything else. The project also targets HTTP, TCP and WebSocket services, so a database connection or a raw TCP listener is in scope, not just web traffic.

SSH remote port forwarding as the transport

The README states that Portr utilizes SSH remote port forwarding under the hood to securely tunnel connections. That choice has consequences worth spelling out. SSH is already installed on most developer machines and most servers, it authenticates with keys rather than a bespoke token scheme, and it gives you a transport that network engineers already know how to reason about. The cost is that the client and the server must agree on SSH reachability, and that the server side is something you run. Portr is not a hosted service in the way that some tunnel tools are. The README's quick start begins with set up a Portr server or use an existing one, then install the client, then start a tunnel. So the architecture is two-part by design: a server component that terminates public connections and a client that registers a tunnel and forwards traffic back over the SSH connection. The repository is written in Go and includes a Svelte-based admin dashboard, judging by the topics list and the dashboard feature described in the README.

What happens when you run portr http 9000

The README gives a compact example. Running portr http 9000 starts an HTTP tunnel, and the documentation states it does three things immediately: it creates a public HTTPS URL that forwards to your local service, it starts the Portr inspector locally at http://localhost:7777, and it persists HTTP request logs locally so they can be queried from the CLI. To pin the tunnel to a subdomain, the README shows portr http 9000 --subdomain amal-test. That flag matters for teams, because a stable subdomain means webhook URLs and callback registrations do not have to be rewritten every time someone restarts a tunnel. The inspector is the part that distinguishes Portr from a plain SSH forwarding command. It lets you inspect incoming HTTP requests and responses, replay stored requests, inspect headers and payloads, and monitor upgraded WebSocket sessions and captured frames. WebSocket frame capture is unusual for a tunnel tool and is the feature most likely to decide adoption for anyone debugging a socket-based service.

The logs CLI and its SQLite store

Request data captured by the inspector is also available from the command line, backed by a file at ~/.portr/db.sqlite. The README gives three examples: portr logs amal-test shows the latest logs for a subdomain, portr logs amal-test /api/ filters by URL substring, and portr logs amal-test --json emits the full stored records as JSON. The README describes these as agent-friendly local request logs, which is a fair description of the design: a local SQLite file plus a JSON output mode is easy for a script or a coding agent to consume without a network round trip. The trade-off is that the store is local. If two people are debugging the same tunnel, they are reading two different databases on two different machines. Nothing in the supplied material describes a shared or server-side log view, so treat per-developer log history as the model unless the docs say otherwise.

Admin dashboard, team management and the server you must run

The README lists an admin dashboard for team, user, and connection management. It does not describe the data model behind teams and users, and it does not state how authentication to the dashboard works. That is a gap worth flagging rather than glossing over. What is clear is that the project expects an operator: the setup section links to a server setup guide and a client installation guide separately, and the quick start assumes a server exists before the client does. For a small team this is a real cost. Someone has to provision a host, follow the server guide, and keep it running. In exchange you get subdomain control, a user model, and traffic that does not pass through a third party's tunnel infrastructure. Whether that exchange is worth it depends on how much you value keeping the connection endpoint inside your own network.

Where Portr is the wrong tool

The README is direct: Portr is not recommended for use alongside production servers. Take that at face value. A tunnel that forwards public traffic into a developer laptop inherits every property of that laptop, including sleep, network changes, and whatever code is currently checked out. There is nothing in the supplied material about horizontal scaling of the server, about redundancy, or about what happens to in-flight connections when the client disconnects. The local inspector listening on http://localhost:7777 is another boundary to think about: it is bound to localhost by default, but it does hold captured request headers and payloads, which can include credentials. The SQLite file at ~/.portr/db.sqlite holds the same data on disk. If you are tunneling a service that carries real customer data, those two local stores are part of your exposure, and the README does not describe retention limits or redaction.

How Portr differs from ngrok and plain ssh -R

The topics list positions Portr as an ngrok alternative and an ngrok replacement, and the practical difference is where the tunnel terminates. With ngrok, the relay is operated by a vendor and you connect a client to it. With Portr, the README's quick start has you set up a Portr server or use an existing one, so the relay is yours to run. The other comparison is the raw command line. A plain ssh -R invocation gives you forwarding and nothing else: no inspector, no replay, no stored request records, no dashboard. Portr adds those on top of the SSH transport, and that added surface is the actual product. If all you need is a forwarded port for a few minutes, ssh -R is fewer moving parts and no server to maintain. If you need to see what arrived, replay it, and hand a subdomain to a teammate, the extra components are the reason to pick Portr.

Maintenance, releases and AGPL-3.0 obligations

The repository is not archived, and the release cadence visible in the supplied material is frequent: v1.0.16, v1.0.17 and v1.0.18 landed within roughly six weeks in mid-2026, with the last push in early September 2026. Frequent patch releases on a 1.0.x line suggest active maintenance, though the material does not describe what changed between them, so read the release notes before upgrading a server that a team depends on. Because the server and the client are separate components, upgrades are not atomic: a client running v1.0.16 against a server running v1.0.18 is a combination the docs may or may not support, and nothing in the supplied material states a compatibility policy. Portr is licensed under AGPL-3.0. That licence carries network-use conditions, which matter more than usual for a project whose whole purpose is serving network traffic. If you modify Portr and let users interact with it over a network, the licence's terms are likely to reach your changes. This is not legal advice; if you plan to fork the server or embed it in something you distribute, read the LICENSE file and get proper review. If you only run it unmodified for internal development tunnels, the practical burden is lighter, but the obligation does not disappear.

Editorial conclusion

Adopt Portr if you run a small team that needs public URLs for development servers and you are willing to operate the server side yourself, since the README points at a separate server setup guide rather than a hosted service. Do not adopt it for production traffic: the README states plainly that it is not recommended for use alongside production servers. Before committing, verify three things on your own host: that the server setup guide covers the SSH port your client will reach, that the admin dashboard's team and user model matches how you hand out subdomains, and that AGPL-3.0 obligations are acceptable for how you plan to modify or redistribute it.

Official sources

  1. amalshaji/portr on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes