A self-hosted web platform for managing reverse SSH tunnels. Register a device once, then reach it from anywhere: monitor tunnel health on a live dashboard, open a terminal in your browser, manage files over SFTP, share access with teammates, and even browse the web through the remote device.
- Tunnel dashboard — live online/offline status and per-hop latency (you → Telepy → device), in list or card view.
- Guided tunnel creation — a five-step wizard issues keys and generates ready-to-run connection scripts: plain SSH, AutoSSH, systemd service, PowerShell, Docker Run, and Docker Compose, plus a single-use
curlURL for fetching the script on the target machine. - Web terminal — multi-tab xterm.js terminal over WebSocket, with per-user sessions and live latency readout.
- File manager — SFTP-based file browser alongside the terminal for uploading and downloading files on the device.
- Remote proxy browser — launch a real Chromium desktop (KasmVNC) whose traffic is tunneled through the target device, so external requests appear to come from that machine.
- Sharing & permissions — share tunnels with other users under hierarchical VIEW / EDIT / ADMIN permissions.
- Keys & logs — manage authorized keys and inspect SSH server logs from the UI.
- Authentication — Google OAuth2 or username/password, JWT-backed API. The first user to log in becomes the superuser.
- Internationalization & theming — English, 繁體中文, and 日本語; light and dark themes.
Go to Tunnels → Create Tunnel, paste the device's SSH public key, and follow the wizard. Run the generated script on the device and the tunnel comes online.
Click Terminal on any online tunnel to get a shell on the device, straight from the browser.
Click Browser on an online tunnel to start a Chromium session that browses the web through the device (SSH SOCKS proxy + KasmVNC streaming).
The device keeps a reverse SSH connection (ssh -NR <port>:localhost:22 telepy@server) to Telepy's SSH container, which assigns each tunnel a dedicated port. The web terminal, file manager, and proxy browser all reach the device through that port — no inbound firewall rules or public IP needed on the device side.
Telepy runs as six containers orchestrated by Docker Compose:
| Service | Role |
|---|---|
traefik |
Reverse proxy; routes /api/* & /ws/* to the backend, everything else to the frontend |
frontend |
Next.js web UI |
backend |
Django + DRF + Channels (REST API & WebSocket terminal) |
redis |
Cache and channel layer |
ssh |
OpenSSH server that terminates the reverse tunnels |
kasm-browser |
KasmVNC + Chromium for remote browser sessions |
Requires Docker with the Compose plugin.
-
Create your environment file and adjust as needed:
cp .env.example .env
-
Generate the SSH server keys:
./telepy.sh keygen
-
Build and start the stack:
docker compose up -d --build
-
Open
http://localhost:<WEB_SERVER_PORT>/login(default:http://localhost:8787/login) and sign in.
Note
The first user created becomes the superuser — whether via Google login or ./telepy.sh create-superuser (check dev-scripts/dev-create-superuser.sh to change the default username/password before running it).
- Tunnels → Create Tunnel, paste the device's SSH public key, and complete the wizard (add at least one OS username that exists on the device).
- Append the shown service key to
~/.ssh/authorized_keyson the device. - Run the generated connection script on the device (SSH for quick tests, AutoSSH/systemd/Docker for something persistent). Scripts can be retrieved any time from the tunnel's Scripts action.
- When the tunnel shows Online, the terminal, file manager, and remote browser are ready to use.
Environment variables in .env:
| Variable | Default | Description |
|---|---|---|
PROJECT_NAME |
main |
Suffix for container names |
DEBUG |
false |
Django debug mode |
WEB_SERVER_PORT |
8787 |
Port Traefik exposes the web UI on |
REVERSE_SERVER_SSH_PORT |
24242 |
Port devices connect their reverse SSH to |
SOCIAL_GOOGLE_CLIENT_ID |
— | Google OAuth client ID |
SERVER_DOMAIN |
localhost |
Public hostname of your Telepy server |
INTERNAL_API_TOKEN |
— | Secret for internal service-to-service calls |
./telepy.sh wraps the day-to-day maintenance scripts:
Usage: ./telepy.sh sub-command [args]
Sub-commands:
keygen: Generate SSH keys for Telepy service.
create-superuser: Create an admin account for Telepy management.
shell: Create a shell to run arbitrary command.
ipython: Create a shell to run ipython.
supervisorctl: Attach to supervisor control shell.
ssh-shell: Similar to 'shell', but for ssh container.
migration: Run migration process.
backend-debug: Recreate and attach to backend container.
collect-static: Collect static files to increase rendering speed.
django-startapp: Create a new Django app.
Log in first, then visit:
- Swagger UI —
http://localhost:<WEB_SERVER_PORT>/api/__hidden_swagger - ReDoc —
http://localhost:<WEB_SERVER_PORT>/api/__hidden_redoc - Django admin —
http://localhost:<WEB_SERVER_PORT>/api/__hidden_admin/
Nat Lee |
H. Alice |
Boris Lok |


