Tunnel Server Development Setup
Set up the Portr tunnel server for local development, so you can run and contribute to the SSH-based tunneling backend on your machine.
The tunnel server is built using Go and handles the server-selected client tunnel transport for HTTP/TCP connections. SSH is the default transport; WebSocket can be selected with PORTR_TRANSPORT=websocket.
Requirements
- Go (1.25+)
- PostgreSQL (16+) or SQLite (3.0+)
Setup Process
Configure environment variables
Create a new .env file using the .env.template file as a reference.
Start the server
You should see output similar to:
With the default PORTR_TRANSPORT=ssh, this starts:
- SSH tunnel server on port
:2222 - Proxy server on port
:8001for wildcard HTTP and upgraded WebSocket traffic
With PORTR_TRANSPORT=websocket, the proxy also serves the WebSocket tunnel
endpoint at /_portr/tunnel/connect instead of starting the SSH server.
When running the combined server with go run ./cmd/portrd start all, the admin
server listens on :8000 by default and the selected tunnel transport listens on
its configured port.
Server Architecture
The tunnel server consists of several components:
Tunnel Transport
- Starts SSH or WebSocket based on
PORTR_TRANSPORT - Handles incoming tunnel connections from clients
- Authenticates clients using tokens
Proxy Server
- Routes incoming HTTP requests to the appropriate tunnels
- Handles subdomain routing
- Manages SSL termination in production
Cron Jobs
- Cleans up expired tunnel connections
- Performs maintenance tasks
Development Workflow
Available Commands
Configuration
For all configuration variables, check out the tunnel server config file.
Key configuration options include:
- Database connection: PostgreSQL connection string
- Transport settings:
PORTR_TRANSPORT,PORTR_SSH_URL,PORTR_WS_URL, and authentication - Proxy settings: HTTP server configuration
- Security settings: Token validation and access control
Testing Tunnel Connections
Make sure the admin server is running before testing tunnel connections, as it handles client authentication.
Local Testing
- Start the admin server
- Start the tunnel server
- Build and run the client to create a test tunnel
Connection Flow
- Client reads
transportfrom the generated config - Client connects to
ssh_urlorws_urlbased on that transport - The selected tunnel transport validates the client token with the server
- HTTP tunnels register one or more workers; TCP tunnels register one remote TCP listener
- Proxy server routes incoming requests or TCP bytes to the client
Troubleshooting
Common Issues
Port conflicts: Ensure the selected transport port is available (2222 for SSH by default, 8001 for WebSocket/proxy by default).
Database connection errors: Verify your PostgreSQL instance is running and accessible.
Tunnel connection failures: Check that the generated client config matches the server transport and that the client has valid credentials.
Debugging
Enable tunnel debug logging with:
View detailed logs to troubleshoot connection issues:
Admin Development Setup
Set up the Portr admin dashboard for local development, so you can run and contribute to the team management interface on your machine.
Client Development Setup
Set up the Portr client CLI for local development, so you can build, run, and contribute changes to the tunnel client on your machine.