Run a worker tunnel
Stand up a long-lived, team-owned tunnel that survives logout and reboot — create, install, start, monitor, and tear down.
You want to run a tunnel that stays up after you log out, that has a stable team-scoped URL, and that you can monitor with status and logs. That's a worker tunnel — long-lived, team-owned, and managed by the platform service supervisor (launchd on macOS, systemd-user on Linux).
You'll need:
- An authenticated CLI (
justtunnel auth). - A team you belong to. Worker tunnels are team-only — switch with
justtunnel context use team:<slug>before anyworker ...command. - macOS or Linux for the managed-service path. Windows can run workers in the foreground with
worker startbut does not supportworker install(see the CLI repo'sdocs/windows-recipe.mdfor a Task Scheduler recipe).
Steps
1. Switch into the team context
justtunnel context use team:acme
Every worker command resolves the team from the active context. If you skip this step, worker ... exits with worker commands require a team context.
2. Create and install the worker (one-liner)
justtunnel worker install staging-api
Installed worker "staging-api" (id=wrk_abc123) in team:acme
url: https://staging-api--acme.justtunnel.dev
worker install does three things in order:
- Registers the worker server-side (idempotent — re-running on an existing worker is fine).
- Writes the per-worker config to
~/.justtunnel/. - Installs the platform-native service definition (
launchduser agent on macOS,systemd --userunit on Linux).
The derived public URL is <name>--<team-slug>.justtunnel.dev. The CLI validates that this fits within the 63-character DNS label before it contacts the server.
Linux user-linger prompt
On Linux, the installer may ask whether to enable systemd user-linger (so the service runs after you log out). You have three choices:
- Approve the prompt — the service stays up across logout and reboot.
- Pass
--no-linger— the service runs only while you're logged in; on logout it stops. - Pass
--non-interactive— equivalent to--no-lingerfor scripted installs (CI, provisioning).
On macOS, launchd-user agents survive logout natively, so --no-linger and --non-interactive are no-ops. The CLI emits a stderr warning if you pass them on macOS so scripted callers see the misuse.
3. Confirm it's running
justtunnel worker status
Workers in team:acme:
NAME SERVER LOCAL LAST SEEN
staging-api active launchd:running 2026-05-06 12:34:56Z
The LOCAL column reports what the platform supervisor sees. launchd:running (macOS) or systemd:running (Linux) means the service is up. none means the worker isn't supervised — typically because it was created with worker create and never installed.
For a verbose detail view of one worker, pass its name:
justtunnel worker status staging-api
Worker: staging-api
Context: team:acme
Server: active
Local: launchd:running
Last Seen: 2026-05-06 12:34:56Z
4. Tail the logs
justtunnel worker logs staging-api -f
-f follows the active log file in real time, just like tail -f. Press Ctrl-C to exit. Other modes:
justtunnel worker logs staging-api— last 1000 lines (default).justtunnel worker logs staging-api -n 100— last 100 lines. The--linesvalue is capped at 100,000 to protect against typos.justtunnel worker logs staging-api --all— every retained day, oldest first.
The supervisor writes to ~/.justtunnel/logs/worker-<name>.log. Daily rotation and 7-day / 100 MB retention are enforced automatically.
5. Run the worker in the foreground (for debugging)
If you suspect the supervisor is masking an error, run the same code path directly:
justtunnel worker start staging-api
This blocks until SIGINT/SIGTERM or until the server closes the session with a terminal status. Logs stream to stderr (not the rotated log file) — useful when you want to watch live without -f.
6. Tear it down
When you no longer need the worker:
justtunnel worker uninstall staging-api
Uninstalled worker "staging-api"
uninstall stops the service, removes the local service definition, and deletes the local config. By default the server-side worker record is preserved so you can re-install with the same name without losing identity. To also delete the server-side record:
justtunnel worker uninstall staging-api --delete-on-server
Uninstalled worker "staging-api" (server-side row quarantined; permanent removal in 30 days)
The server soft-deletes for 30 days; a background reaper removes the row after that. Run worker list --all to see quarantined workers.
If the install is wedged and the normal teardown fails, use --force:
justtunnel worker uninstall staging-api --force
--force continues past per-step failures, prints warnings to stderr, and exits 0. Useful when local config is corrupt or the supervisor is stuck.
For local-only cleanup without touching the supervisor (rarely what you want), use justtunnel worker rm instead.
Verify
After step 2, hit the worker URL from any machine:
curl -I https://staging-api--acme.justtunnel.dev
You should see whatever your local service returns (HTTP/2 200, etc.). After step 6 the same URL should fail to resolve or return a 404 — the worker is gone.
To verify the service is actually managed by the platform supervisor, check it directly:
# macOS
launchctl list | grep justtunnel
# Linux
systemctl --user status justtunnel-worker-staging-api
worker status already wraps this in a portable form, but the native commands are useful when something is misbehaving.
Common issues
worker commands require a team context. You're onpersonal. Runjusttunnel context use team:<slug>first.worker install is not supported on windows. Windows has no managed-service adapter. Useworker start <name>in the foreground under your own supervisor (Task Scheduler, NSSM, etc.) — see the CLI repo'sdocs/windows-recipe.md.- 403 from
worker start. Most often, the worker was created withworker createand never had a service token provisioned. Runworker install <name>to fix it. Other causes: team suspended, membership revoked. - Linger configuration failed (Linux). The unit is installed but system-wide linger is not configured. The worker runs in the current session; re-run
worker installafter fixing the underlying issue, or accept session-bound behavior. worker rmdid not stop the service.rmonly removes local config (and optionally the server record); it does not touch the supervisor. Useworker uninstallfor a managed worker.
Related
justtunnel worker— full CLI reference for every subcommand.justtunnel context— switch into a team context before running worker commands.- Switch between accounts (contexts) — task-oriented walkthrough for context switching.
- Worker tunnels — concept doc explaining how workers differ from ad-hoc tunnels.
- Worker won't start — troubleshooting guide for failed installs.