5.7 KiB
5.7 KiB
EasyBot Tunnel Client
Lightweight reverse-tunnel client that connects private services (databases, APIs, etc.) behind firewalls to your EasyBot runtime via a secure WebSocket connection.
The client connects outbound to your EasyBot server — no inbound ports, firewall rules, or public IPs needed on the client side.
Prerequisites
- An EasyBot instance with the Tunnels feature enabled
- A tunnel created from the EasyBot dashboard (Settings > Tunnels)
- The token shown once at creation time (starts with
eb_tun_)
Quick Start (Docker)
docker run -d --restart always --name easybot-tunnel \
-e TUNNEL_SERVER=wss://YOUR_RUNTIME_URL/ws/tunnel \
-e TUNNEL_TOKEN=eb_tun_YOUR_TOKEN_HERE \
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
Replace:
YOUR_RUNTIME_URLwith your EasyBot runtime hostname (e.g.runtime.example.com)eb_tun_YOUR_TOKEN_HEREwith the token from the dashboard
Installation by OS
Linux (Docker)
# Pull and run
docker run -d --restart always --name easybot-tunnel \
-e TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel \
-e TUNNEL_TOKEN=eb_tun_xxxxx \
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
# Check logs
docker logs -f easybot-tunnel
Linux (systemd, without Docker)
# Install Node.js 20+
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt-get install -y nodejs
# Download and install
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install --omit=dev
npm run build
# Create systemd service
sudo tee /etc/systemd/system/easybot-tunnel.service <<EOF
[Unit]
Description=EasyBot Tunnel Client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Restart=always
RestartSec=5
Environment=TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel
Environment=TUNNEL_TOKEN=eb_tun_xxxxx
WorkingDirectory=$(pwd)
ExecStart=/usr/bin/node dist/index.js
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now easybot-tunnel
sudo journalctl -u easybot-tunnel -f
Windows (Docker Desktop)
docker run -d --restart always --name easybot-tunnel `
-e TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel `
-e TUNNEL_TOKEN=eb_tun_xxxxx `
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
Windows (as a service, without Docker)
# Install Node.js 20+ from https://nodejs.org
# Download and build
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install --omit=dev
npm run build
# Install as Windows service using nssm (https://nssm.cc)
nssm install EasyBotTunnel "C:\Program Files\nodejs\node.exe" "C:\easybot-tunnel-client\dist\index.js"
nssm set EasyBotTunnel AppEnvironmentExtra TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel TUNNEL_TOKEN=eb_tun_xxxxx
nssm set EasyBotTunnel AppRestartDelay 5000
nssm start EasyBotTunnel
macOS (Docker)
docker run -d --restart always --name easybot-tunnel \
-e TUNNEL_SERVER=wss://runtime.example.com/ws/tunnel \
-e TUNNEL_TOKEN=eb_tun_xxxxx \
repo.pyp.ar/public-pull/easybot-tunnel-client:1.0
macOS (launchd, without Docker)
# Install Node.js
brew install node@22
# Download and build
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install --omit=dev
npm run build
# Create launch agent
cat > ~/Library/LaunchAgents/com.easybot.tunnel.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.easybot.tunnel</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>$(pwd)/dist/index.js</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>TUNNEL_SERVER</key><string>wss://runtime.example.com/ws/tunnel</string>
<key>TUNNEL_TOKEN</key><string>eb_tun_xxxxx</string>
</dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/com.easybot.tunnel.plist
Environment Variables
| Variable | Required | Description |
|---|---|---|
TUNNEL_SERVER |
Yes | WebSocket URL of your EasyBot runtime (e.g. wss://runtime.example.com/ws/tunnel) |
TUNNEL_TOKEN |
Yes | Authentication token from the dashboard (starts with eb_tun_) |
How It Works
- The client connects to your EasyBot runtime via WebSocket (outbound only)
- The server sends a config with port mappings (e.g. "forward localhost:5432 on this tunnel")
- When EasyBot needs to reach your private service, it opens a TCP connection through the tunnel
- Traffic flows bidirectionally: EasyBot runtime <-> WebSocket <-> Tunnel Client <-> Your private service
All port mappings are configured server-side in the EasyBot dashboard. The client only needs the server URL and token.
Verifying the Connection
After starting the client, check the EasyBot dashboard (Tunnels section). Your tunnel should show:
- Status: Connected (green)
- Latency in ms
- Client IP
Troubleshooting
| Issue | Solution |
|---|---|
| "Connection refused" | Check TUNNEL_SERVER URL is correct and reachable |
| "Authentication failed" | Verify TUNNEL_TOKEN is correct (not expired/regenerated) |
| Keeps reconnecting | Check firewall allows outbound WSS (port 443) |
| Target not reachable | Ensure the target service (e.g. PostgreSQL) is running and accessible from the machine running the tunnel client |
Building from Source
git clone https://repo.pyp.ar/public-pull/easybot-tunnel-client.git
cd easybot-tunnel-client
npm install
npm run build
node dist/index.js