Skip to Content
Teitunnel

Concepts

Run modes

Where this computer's Cloudflare Tunnel connector runs: in the Teitunnel app, as an Always-on launchd, systemd or Task Scheduler service that survives quitting and restarts, in the foreground with teitunnel up, with a web dashboard with teitunnel serve, or in Docker.

Your routes answer only while a connector for their tunnel (a cloudflared process) runs somewhere and holds its connections to Cloudflare. Teitunnel can run this computer's connectors in several ways. They all serve the same tunnel and the same routes, so you can switch between them without touching Cloudflare.

ModeRuns whileStarted byGood for
With the app (default)Teitunnel is open, including when only its menu bar or tray icon showsThe appA laptop you work on
Always-onAlways: from login (or boot, on servers), even after you quit the appYour system's service managerA desktop that serves things all day, a home server
teitunnel upThe command runsYou, a terminal, or a process supervisorServers, containers, CI
teitunnel serveThe command runsSame as upServers you want to see and manage from a browser

With the app

This is where every tunnel starts. The app starts a connector for each of this computer's tunnels, watches its health, and restarts it with increasing delays (from 1 second up to a minute) if it crashes. If it crashes more than five times in two minutes, Teitunnel stops retrying and the Doctor shows why, with its last log lines.

  • The tunnel's run token is handed to cloudflared in its environment, never on the command line, so other programs can't read it from the process list.
  • Closing the window keeps everything running in the menu bar (or the tray on Windows and Linux). Settings ▸ General ▸ Open at login starts Teitunnel there when you log in, without opening a window.
  • Quitting (⌘Q, or Quit Teitunnel from the menu bar) while routes run through the app asks first: Your routes stop when Teitunnel quits. They can keep running in the background instead, and start again when you log in. Choose Keep Routes Running to switch them to Always-on, or Quit Anyway.
  • Stop Routes on This Mac in the menu bar, or Stop on This Mac in Tunnels, stops the connectors on purpose (the menu bar icon doesn't flag it as a problem); Start on This Mac starts them again.

Always-on

Tunnels: this computer's tunnel with its connector, the Keep running when Teitunnel quits switch and traffic

In Tunnels, select the tunnel and turn on Running ▸ Keep running when Teitunnel quits. Teitunnel installs a service that runs the connector without the app:

macOSWindowsLinux
ServiceA launch agent in ~/Library/LaunchAgentsA Task Scheduler taskA systemd --user unit
StartsAt loginAt logonAt login (and at boot with lingering, see below)
Restarts after a crashYes (launchd)Yes (Task Scheduler)Yes (systemd)
  • The service reads the run token from a file only your user can read (0600) in Teitunnel's data folder. It's removed when you turn Always-on off. This is the only place a secret is ever written to a file.
  • Its log goes to Teitunnel's data folder, and the app shows it in Tunnels ▸ Logs as usual.
  • The app only observes an Always-on connector; it never supervises it. Quitting or updating the app can't take those routes down.
  • On Linux, user services stop when you log out. Run loginctl enable-linger once to keep them running after logout and start them at boot.

Switching doesn't drop your routes. When you turn Always-on on or off, the new connector starts and must connect to Cloudflare before the old one stops (Switching without dropping connections…). If it doesn't connect within 30 seconds, the old one keeps running and you're told why, for example The always-on connector didn't connect within 30 seconds. This Mac keeps using the app's connector.

From a terminal:

teitunnel always-on on                   # every tunnel of the account
teitunnel always-on on --tunnel staging  # one tunnel
teitunnel always-on status
teitunnel always-on off
$ teitunnel always-on status
laptop	always on, running
staging	runs with the app

Run as root on a Linux server, teitunnel always-on on installs a system unit instead, which starts at boot before anyone logs in and runs sandboxed. See servers.

teitunnel up

teitunnel up runs every tunnel of this computer, for every connected account, in the foreground until you press Ctrl-C or the process is stopped. It's the command for servers and containers, and for any process supervisor (systemd, runit, Docker, Kubernetes).

$ teitunnel up
Running 1 tunnel(s): laptop. Press Ctrl-C to stop.
laptop: connecting
laptop: connected
  • Tunnels that are Always-on are left to their service: staging runs as a service already (Always-on); leaving it to it.
  • In a folder with a project file (teitunnel.yml), up shows and applies its plan first, and runs its shares for as long as it runs. --file picks another file, --no-project ignores it, and --yes, --replace and --strict work as in project apply.
  • While it runs, up also does what the app would: it checks each route's uptime every minute and prints alerts, applies pauses and schedules of this computer's routes (when the app isn't doing it already), and points back any route an ended inspection left behind.
  • On a server without a keychain, give it the API token in the environment: CLOUDFLARE_API_TOKEN, or CLOUDFLARE_API_TOKEN_FILE for Docker and Kubernetes secrets. It's used for that command and never stored.

teitunnel serve

teitunnel serve does everything up does and adds a small web dashboard and JSON API, listening on 127.0.0.1:8765 by default. Set its password with teitunnel serve --set-password, create keys for automation with teitunnel api-key create, and put TLS in front of it before using --listen on a public address with --allow-remote. See servers and the API.

Docker

The teispace/teitunnel image runs teitunnel up by default, keeps its state in /data, and uses teitunnel routes --check as its health check:

docker run --rm -e CLOUDFLARE_API_TOKEN -v teitunnel:/data \
  teispace/teitunnel route add app.yourhost.com http://web:80 --yes
docker run -d --name teitunnel --restart unless-stopped \
  -e CLOUDFLARE_API_TOKEN -v teitunnel:/data --network my-app teispace/teitunnel

Inside a container, localhost is the container itself: point routes at other containers by their service name. See Docker Compose.

Several places at once

A tunnel can run on several machines, and on one machine in more than one mode, at the same time. Cloudflare then splits requests between the connectors. That's how load balancing and zero-downtime switches work, but if two machines run the same tunnel by accident, some visitors reach the wrong one. The Doctor warns when another machine runs this computer's tunnel, and when two connectors on this computer do.

cloudflared updates

When Teitunnel installs a new cloudflared, running connectors move to it one account at a time. A connector run by the app restarts in place in a few seconds. An Always-on connector is covered by a temporary one while its service is reinstalled, so routes stay up throughout; if the reinstall fails, the temporary connector keeps serving and you're told.

Troubleshooting

  • "Always-on isn't available on this system." No supported service manager was found (for example, a Linux system without systemd). Use teitunnel up under your own supervisor.
  • "The background service couldn't be set up: …" The service manager refused the service. The app's connector keeps serving; the detail says why.
  • Routes stop when you log out (Linux). Run loginctl enable-linger.
  • "This machine has no tunnel to run. Add a route first (teitunnel route add …)." teitunnel up found no tunnel for this computer in any connected account.
Edit on GitHub

Last updated on

On this page