PiTunnel client makes your local services accessible over the internet.
- Cross-Platform: Windows, macOS and Linux support
- Web Tunnel: Route HTTP/HTTPS traffic through tunnel
- TCP Tunnel: SSH, RDP, MySQL, PostgreSQL and other protocols
- Custom Domain: Use your own domain instead of auto-generated subdomain
- WebSocket Support: Full bidirectional WebSocket proxy (including HMR)
- Auto Reconnect: Automatic reconnection when internet connection drops
- System Service: Auto-start on system boot
- Interactive CLI: Easy-to-use command line interface
# Install globally from npm
npm install -g pi-tunnel-client# First login to server
piclient login
# Start a tunnel
piclient start
# Check status
piclient status
# Stop tunnel
piclient stop
# Logout from server
piclient logout| Command | Description |
|---|---|
piclient login |
Login to PiTunnel server |
piclient logout |
Logout from server (stops all tunnels) |
piclient start |
Start new tunnel (interactive) |
piclient start -b |
Start in background |
piclient stop |
Stop tunnel (interactive) |
piclient stop -n <name> |
Stop specific tunnel |
piclient stop --all |
Stop all tunnels |
piclient status |
Status and statistics |
piclient list |
List saved connections |
piclient delete |
Delete connection |
piclient config --show |
Show configuration |
piclient install |
Auto-start on system boot |
piclient uninstall |
Remove auto-start |
piclient update |
Update to latest version |
piclient update --check |
Check for updates without installing |
# Install
piclient install
# Uninstall
piclient uninstall| Platform | Method | Location |
|---|---|---|
| Windows | Task Scheduler | Starts on login |
| macOS | LaunchAgent | ~/Library/LaunchAgents/ |
| Linux | systemd user service | ~/.config/systemd/user/ |
Configuration file location:
- Windows:
%APPDATA%\PiTunnel\config.json - macOS/Linux:
~/.pitunnel/config.json
{
"server": "ws://your-server:8081",
"token": "your-auth-token",
"domain": "tunnel.example.com"
}| Parameter | Description |
|---|---|
server |
Server WebSocket URL |
token |
Authentication token |
domain |
Domain info received from server |
PiTunnel fully supports WebSocket connections. Hot Module Replacement (HMR) for frameworks like React, Vite, and Next.js works automatically.
How it works:
- Client starts tunnel with target
127.0.0.1:3000 - Server automatically starts listening on port 3000 as well
- Browser requests
ws://tunnel-name.domain.com:3000/ws - Server forwards the request to client
- Client connects to local application
No additional configuration required! Everything works automatically thanks to the server's dynamic port system.
Client automatically waits when internet connection drops and reconnects when connection is restored:
❌ Disconnected from server
📡 Waiting for internet connection...
✅ Internet connection restored
🔄 Reconnecting in 3 seconds...
# React app running locally (port 3000)
npm start
# Start tunnel in another terminal
piclient start
# Type: Web (HTTP/HTTPS)
# Target: 127.0.0.1:3000
# Now accessible at http://your-tunnel.domain.com
# HMR (Hot Module Replacement) works automatically!piclient start
# Type: TCP
# Protocol: SSH
# Target: 127.0.0.1:22
# Connect remotely:
ssh user@your-tunnel.tcp.domain.compiclient start
# Type: TCP
# Protocol: MySQL
# Target: 127.0.0.1:3306
# Connect remotely:
mysql -h your-tunnel.tcp.domain.com -u user -p# Express/Flask/Django running locally (port 8080)
piclient start
# Target: 127.0.0.1:8080
# Type: Web
# Now API accessible at http://your-tunnel.domain.comYou can use your own domain instead of the auto-generated subdomain:
piclient start
# Type: Web (HTTP/HTTPS)
# Target: 127.0.0.1:3000
# Domain Type: Custom domain
# Custom domain: myapp.example.com
# Now accessible at http://myapp.example.comDNS Setup:
- Point your domain to the tunnel server IP (A record or CNAME)
- Wait for DNS propagation
- Start tunnel with custom domain option
Example DNS Configuration:
myapp.example.com A YOUR_TUNNEL_SERVER_IP
You can also use the --custom-domain flag directly:
piclient connect -n myapp -s ws://server:8081 -t localhost:3000 --custom-domain myapp.example.compiclient start
# Type: TCP
# Protocol: RDP
# Target: 127.0.0.1:3389
# Connect remotely (Windows):
mstsc /v:your-tunnel.tcp.domain.comServer can send commands to client via API:
| Command | Description |
|---|---|
stop |
Stop the tunnel |
restart |
Restart the tunnel |
# Stop tunnel via server API
curl -X DELETE -H "X-Auth-Token: token" http://server:8082/tunnels/my-tunnel
# Client output:
# ⚠️ Stop command received: API request- Check your internet connection
- Make sure server address is correct
- Check firewall settings
Check your token:
piclient config --showTo reset:
piclient config --token YOUR_NEW_TOKEN- Make sure local service is running
- Make sure you specified the correct port
- Check tunnel status with
piclient status
PiTunnel automatically supports WebSockets. If you're having issues:
- Make sure server opened the dynamic port (check server logs)
- Make sure the port is open in firewall
- Restart the server
- Node.js: 18.0.0 or higher
- Windows: Windows 10/11
- macOS: macOS 10.15 (Catalina) or higher
- Linux: Distributions with systemd support (Ubuntu, Debian, Fedora, CentOS, etc.)
MIT