Tunly
Tunly is a lightweight, open-source HTTP tunnel solution for developers who want full control and instant setup. No quotas. No dashboards. No tracking. Just you, your app, and a tunnel pure and simple.
Install / Use
/learn @0xReLogic/TunlyREADME
Tunly
Tunly is a simple, lightweight, and open-source HTTP tunnel solution for exposing local applications to the internet.
Motivation
Tunly is built for developers, makers, and anyone who wants:
- Access local applications from anywhere without hassle
- No login, no dashboard, no limits
- 100% open source and self-hostable
- Easy distribution: simple setup with token-based authentication
Key Features
- Zero Configuration: No login, no dashboard, and no complex registration.
- Advanced Security: Secure JWT-based authentication with IP binding and single-use protection.
- High Performance: Native HTTP/2 support with multiplexing and transparent Zlib compression.
- Full Observability: Prometheus metrics (
/metrics), structured JSON logging, and a built-in session activity viewer (/_log). - Production Built: Lightweight binary with persistent connection pooling and enforced security limits.
- Self-Hostable: Easily deploy on any VPS or Cloud (DigitalOcean, Vultr, Koyeb, etc.).
- Privacy First: 100% open-source with zero tracking or telemetry.
When to Use Tunly?
Demo & Presentations
Client wants direct access to your app? But your project is still on localhost?
Solution: Tunly makes your localhost accessible from anywhere in 30 seconds.
Client Testing
Client needs to test new features but you haven't deployed to production yet?
Solution: Share tunnel URL, client can test immediately without complex setup.
Development & Debugging
Remote work but need access to apps on your home computer?
Solution: Tunnel from home to office, access applications from anywhere.
Mobile Testing
Need to test web apps on phone but they only run on laptop?
Solution: Tunnel laptop, access from phone via WiFi or data.
Quick Prototyping
Have a new idea, want to share with friends but haven't deployed yet?
Solution: Tunnel localhost, share URL, friends can try immediately.
Private Testing
Want to test apps on the internet without complex setup?
Solution: Tunly provides simple, self-hosted tunneling without hassle.
How to Use
Modes
- Self-host: Run your own server on a VPS or cloud platform and point the client to it.
- Local testing: Run both server and client locally for development.
Self-Hosted Setup
- Download
tunly-clientandtunly-serverfor your OS from Releases - Start the server on your VPS or cloud:
tunly-server --port 8080 - Run the client locally:
tunly-client --remote-host your-server.com:8080 - When prompted, get a token from
http://your-server.com:8080/tokenand paste it - Enter your local address when prompted (default:
127.0.0.1:80) - The client will print your Public URL, e.g.,
https://your-server.com/s/<session>/— share this URL - View the session log:
https://your-server.com/s/<session>/_log
Notes:
- Long flags use kebab-case (e.g.,
--remote-host,--token-url,--allow-token-query).- Default auth uses header
Authorization: Bearer <token>. Query?token=...works only if server enables--allow-token-query.- For self-host without TLS, pass
--use-wss=falseso the client usesws://(the flag accepts an explicit boolean, e.g.,--use-wss=false).
Quick start (from source, via Cargo)
If building from source:
-
Self-host — run your own server, then point client to it.
- Start server (ephemeral token mode):
cargo run --bin tunly-server -- --bind 0.0.0.0:90002a) Start client (interactive, custom server):
cargo run --bin tunly-client -- --remote-host <server-ip-or-host>:9000 --use-wss=false --local 127.0.0.1:80802b) Start client (auto-fetch token):
cargo run --bin tunly-client -- --remote-host <server-ip-or-host>:9000 \ --use-wss=false \ --local 127.0.0.1:8080 \ --token-url http://<server-ip-or-host>:9000/token- Open the Public URL printed by the client, e.g.:
http://<server-ip-or-host>:9000/s/<session>/- Check recent paths accessed by visitors for that session:
http://<server-ip-or-host>:9000/s/<session>/_log
Local offline test (no TLS)
For a quick local test without internet:
- Start server with a fixed token:
cargo run --bin tunly-server -- --bind 127.0.0.1:9000 --token devtoken
- Start client (interactive) and connect over ws:
cargo run --bin tunly-client -- --remote-host 127.0.0.1:9000 --use-wss=false
When prompted, enter devtoken, then your local app address (e.g., 127.0.0.1:8080).
Loginless / Ephemeral Token Mode (no dashboard, no signup)
If you don't want to manage a static token, run the server without --token and without env TUNLY_TOKEN. The server will issue one-time tokens bound to the requester's IP via /token.
- Start server (ephemeral mode)
tunly-server.exe --port 9000 - Client auto-fetch token (advanced)
The client fetches a token fromtunly-client.exe --remote-host <vps-address>:9000 --token-url http://<vps-address>:9000/token/token(JSON or plain text) and connects via WebSocket using that token.
Notes:
- Tokens are one-time use, may be bound to the requester IP, and expire in ~5 minutes.
- Default auth is via header
Authorization: Bearer <token>;?token=query is disabled unless--allow-token-queryis set on the server. - If you prefer a fixed token, set
--token <value>or envTUNLY_TOKENon the server and keep usingconfig.txtor env on the client.
Fixed vs Ephemeral Tokens
-
Fixed Token
- Server: run with
--token <value>or envTUNLY_TOKEN. - Client: paste token when prompted, or set it via
config.txt/TUNLY_TOKEN. - Best for interactive UX testing and simple setups.
- Server: run with
-
Ephemeral Token
- Server: run without
--token(issues one-time tokens via/token, tied tosession+IP, TTL ~5 minutes). - Client: use
--token-url http://<server>:<port>/tokenso the token matches the currentsidautomatically. - Manual prompt is not compatible with Ephemeral mode (will be rejected as invalid).
- Server: run without
Server Hosting Options
- Cheap VPS: DigitalOcean, Vultr, Linode ($5/month)
- Free cloud: Oracle Cloud Free Tier, Google Cloud Free Tier
- Platform-as-a-Service: Render, Railway, Koyeb (easy deployment)
Environment & Deploy
You can configure Tunly using environment variables. See the .env.example files in the root, backend/, and frontend/ directories for templates.
- Server env:
PORT(from platform, e.g., Render, Koyeb) — server listens on this port automatically.TUNLY_TOKEN— optional; if set, server uses fixed-token mode. If not set and--tokenis not provided, server uses ephemeral mode with/tokenissuance.TUNLY_INTERNAL_KEY— optional; if set, restricts/tokenaccess to requests providing this key in theX-Internal-Keyheader (prevents directcurlrequests to your backend).
- Client config:
config.txtwithtoken: <value>(tolerant totoken=/token:/tokenn).- Or env
TUNLY_TOKEN. - Or runtime fetch via
--token-url http://<server>:<port>/token(ephemeral mode).
- Frontend env:
BACKEND_BASE_URL— base URL of your Tunly backend (e.g.,https://<your-app>.koyeb.appor your custom domain). Used by the Next.js proxy routeapp/api/token/route.tsto call/token.TUNLY_INTERNAL_KEY— must match the server's key to allow the frontend to fetch tokens securely via the Next.js API route.
- Deploy on Koyeb:
- Source: Docker → Dockerfile path:
backend/Dockerfile - Health check:
GET /healthz - Environment:
TUNLY_TOKEN(optional): set for Fixed mode; leave empty for Ephemeral mode (/tokenenabled)PORT: injected automatically by Koyeb (no need to set)
- Optional: add a custom domain; Koyeb will provision TLS automatically
- Source: Docker → Dockerfile path:
Security & Limits
/tokenrate limit: 10 requests per 60 seconds per IP- Ephemeral token TTL: ~5 minutes; single use; bound to requester's IP and session id
- Proxy request body limit: 2 MB
- Session idle TTL: ~10 minutes (inactive sessions are garbage-collected)
Logs & Observability
- Server logs each proxied request:
PROXY GET / -> 200 in 16ms (sid=abc123) - Client logs each local request it performs:
LOCAL GET /api -> 200 in 8ms - Session log page lists the last ~50 requests for a session:
- URL:
http://<server>/s/<session>/_log - Shows: Method, URI, Status, Duration (ms)
- Includes quick links to
/, /api, /blogfor quick checks
- URL:
A
Related Skills
canvas
352.5kCanvas Skill Display HTML content on connected OpenClaw nodes (Mac app, iOS, Android). Overview The canvas tool lets you present web content on any connected node's canvas view. Great for: -
himalaya
352.5kCLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
node-connect
352.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
taskflow
352.5kname: taskflow description: Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layer
