Skip to content

a1tem/proxly

Repository files navigation

Proxly

A self-hosted tunneling tool — like ngrok, but on your own domain. Expose local dev servers through subdomains on your VPS.

Don't want to manage a VPS? Join the waitlist for a fully managed, pre-hosted Proxly solution — no server setup required. Join the waitlist →

Demo

How it works

  1. A relay server runs on your VPS behind Nginx (which handles TLS)
  2. You run proxly locally — pick a project from your global config, and it opens one WebSocket per tunnel
  3. Incoming browser requests hit myapp.yourdomain.com → Nginx → relay → WebSocket → your machine → local server → response back

Requirements

  • A VPS with a public IP
  • A domain (e.g. yourdomain.com) with wildcard DNS support
  • Node.js 18+ on both VPS and local machine

Local Setup

Install the CLI

npm install -g @a1tem/proxly

Or from source:

# From the repo root:
npm install
cd packages/client && npm run build
npm install -g ./packages/client

VPS Setup

See VPS_SETUP.md for full setup instructions — Docker (recommended) and manual options, including DNS, TLS certificate issuance, Nginx config, and relay server deployment.


Usage

First run

proxly

On first run (no ~/.proxly.json found), you'll be guided through setup:

Welcome to Proxly!
? Is your relay server self-hosted? Yes

Let's set up your config.
? Username: alice
? Relay host (default: yourdomain.com):
? Secret token (PROXLY_SECRET from your server .env): ****

Config saved to ~/.proxly.json

Let's add your first project.
? Project name: myapp
? Tunnel name: myapp
? Port or target URL: 3000
? Add another tunnel? No
Project "myapp" added with 1 tunnel. Starting...

Multiple projects — interactive picker

When you have multiple projects configured, proxly shows a picker:

$ proxly
? Which project?
  > myapp        — 2 tunnels
    sideproject  — 1 tunnel

Single project — auto-start

With only one project, it starts automatically:

$ proxly
Starting project: myapp
  myapp  https://myapp.yourdomain.com  ->  http://localhost:3000
  myapi  https://myapi.yourdomain.com  ->  http://localhost:8080

Each tunnel reconnects automatically with exponential backoff if the relay is restarted. Press Ctrl+C to close all tunnels cleanly.

Add a project

proxly add

Delete a project

proxly delete

Reset all config

Removes ~/.proxly.json and starts fresh:

proxly reset

Help

proxly help

Tunnel config options

Field Type Description
name string Subdomain to use (e.g. myappmyapp.yourdomain.com)
port number Shorthand for http://localhost:<port>
target string Full URL — http:// or https:// (self-signed certs accepted)

Only one of port or target is required per tunnel entry.


Architecture

Browser
  │  https://myapp.yourdomain.com/path
  ▼
Nginx (TLS termination)
  │  http://127.0.0.1:3100
  ▼
Relay server (packages/server)
  │  WebSocket: wss://yourdomain.com/_proxly/tunnel?secret=...&name=myapp
  ▼
proxly CLI (packages/client)
  │  http://localhost:3000/path
  ▼
Local dev server

Wire protocol

All messages are JSON over WebSocket.

Relay → Client:

Type Fields
request id, method, path, headers, body (base64)
ws-open id, path, headers
ws-message id, data (base64), binary
ws-close id
ping

Client → Relay:

Type Fields
response id, status, headers, body (base64)
ws-message id, data (base64), binary
ws-close id
pong

Development

# Install all dependencies
npm install

# Build both packages
cd packages/server && npm run build
cd packages/client && npm run build

# Watch mode (separate terminals)
cd packages/server && npm run dev
cd packages/client && npm run dev

License

MIT — see LICENSE

About

A self-hosted tunneling tool — like ngrok, but on your own domain. Expose local dev servers through subdomains on your VPS.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages