Skip to content

Tunnel

graft host tunnel forwards a remote container’s port to your local machine, letting you connect to any running service as if it were local.

graft host tunnel <container> [-port <remote>:<local>]

Section titled “graft host tunnel <container> [-port <remote>:<local>]”
Terminal window
graft host tunnel backend -port 5000:8080 # container port 5000 → localhost:8080
graft host tunnel frontend -port 3000 # container port 3000 → localhost:3000
graft host tunnel graft-postgres # auto-detect the exposed port
graft -r azure tunnel backend -port 5000:8080 # via registry

The port mapping is passed with -port (or --port):

FormRemote portLocal port
-port 5000:808050008080
-port 300030003000
omittedauto-detectedsame as remote

What it does:

  1. Connects to the remote server over SSH.
  2. Looks up the container’s IP on the Docker network.
  3. Auto-detects the container’s exposed port when -port is omitted. If several ports are exposed, prompts you to pick one.
  4. Forwards the remote port to your local port and holds the tunnel open until you press Ctrl+C.

Because the remote port is how Graft finds the service, there is no way to choose a local port without naming the remote one too. To reach a container’s port 5000 on local port 8080, write -port 5000:8080.

Use with any local tool — database GUIs, API clients, browsers, or your app’s dev config pointing at your local port.

The SSH connection behind the tunnel is self-healing: if it drops, Graft reconnects without tearing down your local listener, so you can open a tunnel once and leave it running.


For Postgres databases created with graft db init, the db serve command is a shortcut that also prints credentials from .graft/secrets.env.

Note that db serve takes a bare :port for the local port — graft db myapp serve :5433 — which is a different syntax from the -port flag used by host tunnel.