Client usage
The mytunnel client runs on the machine that has the local HTTP service.
It talks to the edge over SSH and starts a reverse tunnel process for public traffic.
Start an HTTP tunnel
Section titled “Start an HTTP tunnel”mytunnel http 3000 --edge mytunnel-edge --base-domain tunnel.example.com --name portalRequired:
- Positional
<local_port>from1through65535. --edge <ssh-destination>.--base-domain <domain>unless the edge config supplies it.
Useful flags:
| Flag | Meaning |
|---|---|
--name <slug> | Request a specific subdomain slug. |
--force | Replace an existing active slug, admin users only. Requires --name. |
--ttl <duration> | Request a lease TTL, such as 5m. |
--reconnect=false | Do not reconnect if the SSH tunnel exits. |
--ssh-bin <path> | Use a non-default SSH binary. |
--no-ssh-mux | Disable SSH muxing for short control commands. |
--remote-bin <path> | Run a non-default remote mytunneld binary. |
Before allocating a lease, mytunnel http checks http://127.0.0.1:<local_port>/.
If the local app is unreachable, no edge lease is allocated.
If the local app returns an empty body or a status code >= 400, the client warns because the tunneled URL will likely show the same behavior.
List leases
Section titled “List leases”mytunnel ls --edge mytunnel-edgemytunnel ls --edge mytunnel-edge --jsonText output:
LEASE_ID HOST OWNER PORT STATE EXPIRES_ATlease_abc portal.tunnel.example.com alice 21000 active 2026-05-05T12:02:00ZIf no owner-scoped leases exist:
no leasesStop a lease
Section titled “Stop a lease”stop releases a lease and removes the Caddy route.
The row remains in the DB as a released tombstone.
mytunnel stop <lease_id|host> --edge mytunnel-edgemytunnel stop <lease_id|host> --edge mytunnel-edge --jsonText output:
released lease_abc (released-lease_abc.invalid)Remove a lease
Section titled “Remove a lease”rm deletes a lease by lease ID, host, or slug.
For an active lease, it removes the Caddy route first.
mytunnel rm <lease_id|host|slug> --edge mytunnel-edgemytunnel rm portal --edge mytunnel-edge --jsonText output:
deleted lease_abc (portal.tunnel.example.com)Run doctor
Section titled “Run doctor”doctor runs edge health and dry-run reconcile checks over SSH.
mytunnel doctor --edge mytunnel-edgemytunnel doctor --edge mytunnel-edge --jsonHealthy text output:
status: okall checks passedDegraded reports include finding codes and next-step hints. Common codes:
| Code | Typical meaning | First action |
|---|---|---|
edge_unreachable | SSH or daemon health failed. | Check SSH reachability, service status, and DB permissions. |
ssh_throttled_suspected | Control traffic looks throttled. | Prefer UFW ALLOW over LIMIT on the mytunnel SSH port. |
caddy_unreachable | Caddy Admin API is down or blocked. | Check Caddy status and loopback Admin API URL. |
reconcile_failed | Route drift or reconcile failure. | Run daemon-side mytunneld ctl reconcile --dry-run --json. |
Remote config override flags
Section titled “Remote config override flags”The client exposes daemon config override flags because tests and ad hoc debugging need them. In production, forced-command SSH keys reject these flags.
| Flag | Production guidance |
|---|---|
--db-path | Use /etc/mytunneld/mytunneld.env instead. |
--base-domain | Acceptable for first quickstart, but edge config should own the value. |
--caddy-admin-url | Must remain loopback-scoped. |
--caddy-server | Should match the Caddy server name in edge config. |
--min-port, --max-port | Edge-owned port range. |
--lease-ttl | Edge-owned default TTL. |
--cleanup-interval, --reconcile-interval | Edge-owned daemon loop intervals. |
--health-timeout | Edge-owned health timeout. |
--log-format | Edge-owned log format. |
--max-leases-per-owner | Edge-owned owner limit. |
Common client errors
Section titled “Common client errors”| Error | Why it happens | Fix |
|---|---|---|
--edge is required | The client needs an SSH destination. | Pass --edge <user@host> or an SSH config alias. |
local app is not reachable | Nothing answered on 127.0.0.1:<port>. | Start the local app or choose another port. |
--force requires --name | Force takeover needs a concrete slug. | Pass --name <slug> or remove --force. |
slug_in_use | An active lease already owns the slug. | Run mytunnel ls, then mytunnel rm <slug>. |
permission_denied | You do not own the lease, or --force is not privileged. | Use the owning SSH user or configure admin users on the edge. |
no_available_port | The edge port range is exhausted or stale. | Run doctor and reconcile or widen the edge port range. |