Guides

Expose a local server

Run an Identity's Tunnel so the world reaches the agent's own port.

A Tunnel gives an Identity a public hostname – orderbot.tigbywire.eu – and forwards every request to a port on the machine the agent runs on. The agent dials out, so nothing has to be open on that machine.

Connect

tigby tunnel connect @orderbot --port 3000

Runs in the foreground until Ctrl-C and reconnects on its own with jittered backoff. A planned handover on Tigby's side costs one such reconnect – the requests already in flight run to their end, and new ones are served as soon as the fresh connection is up. With an Identity Key in the environment (TIGBY_IDENTITY_KEY), the Handle is optional – the key names the Identity.

TIGBY_IDENTITY_KEY=tigby_id_… tigby tunnel connect --port 3000 --json

--json turns every event into one JSON document per line, for a supervisor that watches the process.

Run it as a service

There is no daemon mode: tigby tunnel connect runs in the foreground and ends on Ctrl-C. Keeping a Tunnel up across a reboot is systemd's job, and this is the unit to give it. Save it as ~/.config/systemd/user/tigby-tunnel@.service:

[Unit]
Description=Tigby Tunnel for @%i
After=network-online.target
Wants=network-online.target

[Service]
# The Identity Key is a credential, so it comes from a file rather than from the
# unit – a unit is world-readable, and `systemctl --user show` prints its
# environment back. Put TIGBY_IDENTITY_KEY=tigby_id_… in that file and chmod it
# 0600.
EnvironmentFile=%h/.config/tigby/%i.env
ExecStart=%h/.local/bin/tigby tunnel connect @%i --port 3000 --json
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

Then, for the Identity @orderbot:

install -m 600 /dev/null ~/.config/tigby/orderbot.env
printf 'TIGBY_IDENTITY_KEY=tigby_id_…\n' >> ~/.config/tigby/orderbot.env
systemctl --user daemon-reload
systemctl --user enable --now tigby-tunnel@orderbot
loginctl enable-linger "$USER"     # so it starts at boot, not at your first login
journalctl --user -u tigby-tunnel@orderbot -f

loginctl enable-linger is the line people miss: without it a user unit runs only while you have a session open, so the Tunnel comes back when you log in rather than when the machine does. --json gives the journal one document per event, which is what makes journalctl -o json and any log shipper useful here.

Restart=always is right even though the CLI reconnects on its own: its own jittered backoff covers a blip on the wire, and the restart covers the cases the process cannot – a refused key after a revoke, an upgrade replacing the binary underneath it, the machine coming back.

Where it is reachable

tigby tunnel status @orderbot

Prints the public hostname, the raw-TCP address when the Tunnel has one, and the connect endpoint. Whether anything is serving is answered by one request to the hostname – it reaches the agent's server when one is connected.

Raw TCP

HTTP and WebSocket arrive on the hostname. Raw TCP reaches the Tunnel two ways: by SNI on the collector port – orderbot.tigbywire.eu:8443, one port for every Tunnel, where the server name carries the Handle and your TLS passes through untouched – and on the Tunnel's own allocated port, one number claimed at provisioning and unchanged by reconnects and failover. Both numbers are on GET /api/identities/{handle} as tunnel.sni_port and tunnel.tcp_port, and tigby tunnel status prints them; tigby tunnel connect --tcp shows whichever this Tunnel uses. The bytes are forwarded the same way either way. Not port 443 – that is the HTTP/WS listener, and it drops a payload that is not HTTP.

Limits

A Plan caps streams per Tunnel, new streams per second, and the Org's monthly transfer across all its Tunnels. A refused stream gets 503 on HTTP and a closed connection on raw TCP; Events fire at 80 %, 95 % and when the allowance is spent. Nothing is billed after the fact: where no Credit is loaded and switched on, the cap is the cap until the Plan changes.

When the monthly transfer runs out, the streams that are already open end too – a spent allowance stops what is running, not only what starts next – within one metering flush of the byte that spent it. The Tunnel stays connected, so it serves again the moment the month turns or the Plan changes; there is nothing to reconnect.