Deploy your own private tunnel relay on any VPS (DigitalOcean, Hetzner, AWS Lightsail, etc.) in under 60 seconds.
[ Developer Laptop ] ─── TCP :7890 ───────────────────────► [ expose-server :7890 ]
▲
[ Public Visitor ] ─── HTTPS :443 ──► [ Caddy ] ── :8080 ──────────┘
To route dynamic subdomains (cool-tiger-42.tunnel.yourdomain.com) to your server, add two DNS A records pointing to your VPS IP:
| Type | Name / Host | Value | Purpose |
|---|---|---|---|
| A | tunnel |
<YOUR_VPS_IP> |
Base server address |
| A | *.tunnel |
<YOUR_VPS_IP> |
Wildcard for all dynamic client tunnels |
Tip (Free Wildcard HTTPS): If your domain uses Cloudflare, set the proxy status to Proxied (Orange Cloud) for both records. Cloudflare will automatically terminate wildcard SSL at their edge with zero API keys or rate limits.
git clone https://github.com/kernelshard/expose.git
cd expose/deployCopy the example environment file and set your domain:
cp .env.example .env
nano .envSet DOMAIN to match your relay address:
DOMAIN=tunnel.yourdomain.com
CONTROL_PORT=7890docker compose up -dCheck server logs:
docker compose logs -f expose-serverNow start a tunnel pointing to your self-hosted server:
expose tunnel 3000 --server=tunnel.yourdomain.com:7890You'll get an instant, secure public URL:
🚀 Tunnel started!
✓ Public URL: https://cool-tiger-42.tunnel.yourdomain.com
✓ Forwarding to: http://localhost:3000
If you already have Nginx, Traefik, or Caddy running on your server, you can run expose-server standalone:
docker compose up -d expose-serverThen point your existing reverse proxy to localhost:8080 and forward the Host header.