Get started
BETA
Browse docs
Guides

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 any worker ... command.
  • macOS or Linux for the managed-service path. Windows can run workers in the foreground with worker start but does not support worker install (see the CLI repo's docs/windows-recipe.md for 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:

  1. Registers the worker server-side (idempotent — re-running on an existing worker is fine).
  2. Writes the per-worker config to ~/.justtunnel/.
  3. Installs the platform-native service definition (launchd user agent on macOS, systemd --user unit 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-linger for 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 --lines value 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 on personal. Run justtunnel context use team:<slug> first.
  • worker install is not supported on windows. Windows has no managed-service adapter. Use worker start <name> in the foreground under your own supervisor (Task Scheduler, NSSM, etc.) — see the CLI repo's docs/windows-recipe.md.
  • 403 from worker start. Most often, the worker was created with worker create and never had a service token provisioned. Run worker 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 install after fixing the underlying issue, or accept session-bound behavior.
  • worker rm did not stop the service. rm only removes local config (and optionally the server record); it does not touch the supervisor. Use worker uninstall for a managed worker.

On this page