Noureddine RAMDI / Portr: a self-hosted SSH tunnel with built-in request inspection and logs

Created Mon, 04 May 2026 10:23:02 +0000 Modified Sat, 23 May 2026 20:41:27 +0000

amalshaji/portr

Portr offers a self-hosted alternative to popular tunneling services by exposing local HTTP, TCP, and WebSocket services to the public internet using SSH remote port forwarding. Unlike cloud SaaS solutions like ngrok, Portr gives small development teams full ownership over their tunnel infrastructure, while adding developer-friendly tools like a local request inspector and persistent request logs stored in SQLite.

What Portr does and how it works

Portr is a TypeScript-based tunneling solution designed to expose local services securely over the public internet. The core mechanism under the hood is SSH remote port forwarding, which forwards traffic from a publicly accessible server to a local service behind NAT or firewall.

The architecture consists of two main components: the Portr server and the Portr client. The server runs on a public machine with a stable IP or domain. The client runs on the developer’s machine where the local service resides. When a tunnel is established, the client creates an SSH connection to the server, binding a remote port that forwards incoming requests back to the local service.

Portr supports multiple protocols — HTTP, TCP, and WebSocket — making it versatile for exposing a variety of local applications. The client also ships with a built-in local inspector accessible at http://localhost:7777. This inspector provides real-time request and response inspection, replay capabilities, and WebSocket frame debugging.

Request logs are persisted locally in an SQLite database (~/.portr/db.sqlite), which can be queried via the CLI for audit or debugging purposes. An admin dashboard is included for managing teams, users, and active connections, emphasizing collaborative usage.

The project is licensed under the AGPL-3.0, which encourages open sharing and self-hosting.

Why Portr stands out and its tradeoffs

Portr’s main distinguishing feature is its SSH-based tunneling architecture combined with developer tooling baked into the client. Most tunneling tools rely on proprietary protocols or cloud SaaS models, which abstract away the underlying infrastructure.

By using SSH remote port forwarding, Portr leverages a battle-tested, secure protocol and avoids reinventing a custom tunneling mechanism. This means less complexity on the networking layer and better compatibility with existing SSH infrastructure.

The built-in local inspector is a rare find in the tunneling space. It provides immediate insight into live HTTP and WebSocket traffic, reducing the need to add extra debugging proxies or tools locally. The persistent request log stored in SQLite adds a layer of traceability and offline analysis, which can be useful for debugging tricky issues or auditing traffic.

The codebase, written in TypeScript, appears clean and modular, favoring maintainability and developer experience. The CLI tooling and admin dashboard suggest a focus on usability for small teams rather than just individual developers.

However, the tradeoffs are clear:

  • Self-hosting requires maintaining your own public server, which adds operational overhead compared to managed SaaS.
  • The reliance on SSH remote port forwarding means you need to configure and secure SSH access properly.
  • While the local inspector is useful, it only runs locally and does not provide remote inspection, which might limit collaboration or monitoring in distributed teams.
  • The SQLite-based request logs are local to the client machine, which means no centralized logging unless you build that yourself.

Overall, Portr emphasizes control and transparency over convenience and zero-maintenance.

Quick start with Portr

The README provides straightforward commands to get started once you have a Portr server set up.

portr http 9000

This command exposes a local HTTP service running on port 9000 to the public internet. It also:

  • Creates a public HTTPS URL forwarding to your local service.
  • Starts the Portr inspector locally at http://localhost:7777.
  • Persists HTTP request logs locally for querying.

If you want to pin the tunnel to a specific subdomain, you can run:

portr http 9000 --subdomain amal-test

The README mentions guides for server setup, client installation, and HTTP tunneling, which are essential next steps for production readiness.

verdict

Portr is a solid option for small teams or developers who want full control over their tunneling infrastructure without relying on SaaS providers. Its SSH-based forwarding reduces complexity and leverages existing secure protocols, while the local inspector and request logging improve developer experience.

The project is best suited for users comfortable with managing their own server and SSH access. It may not fit teams needing seamless cloud-hosted solutions, remote centralized logging, or large-scale multi-user collaboration out of the box.

The built-in debugging tooling adds real value, particularly for WebSocket-heavy applications where inspecting frames live can be a pain with other tools. However, the local-only nature of these features and the operational overhead of self-hosting are clear tradeoffs.

If you want a transparent, open-source ngrok alternative that gives you insight into your traffic and full backend control, Portr is worth exploring. Just be prepared to invest some time in infrastructure setup and maintenance.


→ GitHub Repo: amalshaji/portr ⭐ 3,129 · TypeScript