> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vers.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# vers tunnel

> Forward a local port to a port on a VM. Like ssh -L, through the Vers edge.

`vers tunnel` forwards a local port to a port on a VM. Traffic to `127.0.0.1:<local-port>` on your machine is forwarded through the Vers SSH tunnel to `<remote-host>:<remote-port>` inside the VM. If `<remote-host>` is omitted, it defaults to `localhost`.

This is exactly what `ssh -L` does — just with Vers' SSH-over-TLS plumbing handled for you.

## Synopsis

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
# HEAD VM
vers tunnel <local>:<remote>
vers tunnel <local>:<remote-host>:<remote>

# Specific VM
vers tunnel <vm-id|alias> <local>:<remote>
vers tunnel <vm-id|alias> <local>:<remote-host>:<remote>
```

## Examples

### Forward local 8080 to port 80 on HEAD

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
vers tunnel 8080:80
```

### Forward to a specific VM

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
vers tunnel my-vm 5432:5432
```

### Reach a service on a different host from inside the VM

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
# Forward local 9090 to 10.0.0.2:80 via the VM
vers tunnel 9090:10.0.0.2:80
```

Useful when the VM itself has access to an internal network (a database, another VM, a tenant service) that you want to poke at from your laptop.

## When to use `vers tunnel` vs public hostnames

<CardGroup cols={2}>
  <Card title="Public hostname" icon="globe">
    Every VM already has a public hostname: `{vm-id}.vm.vers.sh`. If the service is listening on ports 1024–10000 and should be reachable by other people or agents, just hit the hostname directly. See [Networking](/networking).
  </Card>

  <Card title="vers tunnel" icon="right-left">
    Use a tunnel when the service is bound to `127.0.0.1`, listens on a port outside the public range, or shouldn't be on the public internet at all (databases, admin panels, local dev servers).
  </Card>
</CardGroup>

## How it works

<Steps>
  <Step title="Resolve target">
    Target VM is `<vm-id|alias>` if given, otherwise HEAD.
  </Step>

  <Step title="Establish SSH connection">
    Opens an SSH-over-TLS connection to the VM using your Vers SSH key (the same auth path as `vers connect`).
  </Step>

  <Step title="Bind locally">
    Listens on `127.0.0.1:<local-port>`. Each new connection is forwarded through the SSH channel to `<remote-host>:<remote-port>` on the VM side.
  </Step>

  <Step title="Keep running">
    The tunnel stays up until you Ctrl-C or the connection drops.
  </Step>
</Steps>

## Troubleshooting

* **`address already in use`** — something else is bound to the local port. Pick another.
* **Tunnel opens but the service doesn't respond** — check the remote side is actually listening. From the VM: `ss -tlnp | grep :<port>` or `curl localhost:<port>`.
* **Works at first, then hangs** — the VM paused or the SSH connection dropped. Check `vers status <vm>` and restart the tunnel.

## Common Patterns

### Forward a database port

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
vers tunnel my-db-vm 5432:5432
# then from your laptop: psql -h 127.0.0.1 -p 5432 ...
```

### Reach a private service via a VM

Useful when the VM can talk to something your laptop can't:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
vers tunnel my-vm 9090:10.0.0.2:80
# then from your laptop: curl http://127.0.0.1:9090
```

### Multi-service debugging

Run tunnels in separate terminals to poke at several services from the same VM at once:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
# Terminal 1
vers tunnel my-vm 3000:3000       # app
# Terminal 2
vers tunnel my-vm 5432:5432       # database
# Terminal 3
vers tunnel my-vm 6379:6379       # cache
```

## See also

* [vers connect](/cli-reference/connect) — open an interactive SSH session
* [vers execute](/cli-reference/execute) — run a one-off command
* [Networking](/networking) — public hostnames, port ranges, TLS
