Get started
BETA
Browse docs
CLI Reference

justtunnel worker

Manage long-lived worker tunnels owned by a team — create, install, start, monitor, and tear down.

Worker tunnels are long-lived, team-owned tunnels that survive logout and reboot. Unlike ad-hoc justtunnel <port> tunnels, workers are registered server-side, get a stable subdomain derived from their name, and (on macOS and Linux) run under a platform service supervisor.

worker is a parent command — running it with no subcommand prints help. The eight actions are listed below.

On this page

  • create — create a worker (no supervisor)
  • install — create AND install as a managed service (one-liner)
  • list — list workers in the active team context
  • start — run the worker attach loop in the foreground
  • status — show server-side and local supervisor state
  • logs — read or tail per-worker logs
  • rm — remove a worker (local-only by default)
  • uninstall — uninstall the managed service and tear down

Platform support

PlatformForeground (worker start)Managed service (worker install)
macOSSupportedSupported (launchd-user)
LinuxSupportedSupported (systemd-user)
WindowsSupportedNot supported — use the Task Scheduler recipe in the CLI repo's docs/windows-recipe.md, or run worker start under your own supervisor.

create

Create a worker server-side and write its local config. Does NOT install a service supervisor — pair with install for the managed-service path, or with start to run in the foreground.

Synopsis

justtunnel worker create <name>

Examples

Create a worker named staging-api

justtunnel context use team:acme
justtunnel worker create staging-api
Created worker "staging-api" (id=wrk_abc123) in team:acme
  subdomain: staging-api--acme

The derived subdomain is <name>--<team-slug>. Names must produce a subdomain that fits within the 63-character DNS label limit; the CLI validates this before contacting the server.

Create then start in the foreground

justtunnel worker create build-runner
justtunnel worker start build-runner

start blocks until the WebSocket session ends or you Ctrl-C — useful when wiring the worker into your own process supervisor.

Flags

No flags.

Exit codes

CodeMeaning
0Worker created server-side and local config written.
1Failure — name validation, derived-subdomain length, server error, or local-write rollback.

install

Create the worker server-side (idempotent) AND install a managed service so it survives logout and reboot. This is the one-liner most teams want.

Synopsis

justtunnel worker install <name> [flags]

The command is idempotent across four cases: local present + server present, local present + server missing, local missing + server present, and neither present. Re-running on a fully-configured worker is a no-op except for the supervisor refresh.

Examples

Install a worker on macOS or Linux

justtunnel worker install staging-api
Installed worker "staging-api" (id=wrk_abc123) in team:acme
  url: https://staging-api--acme.justtunnel.dev

On Linux you may be prompted to enable systemd user-linger (so the service runs after you log out). Decline with --no-linger if you want session-bound behavior.

Install non-interactively in CI

justtunnel worker install staging-api --non-interactive

On Linux this is equivalent to --no-linger. On macOS it has no effect (launchd-user agents survive logout natively); the CLI emits a stderr warning so scripted callers see the misuse.

Flags

FlagTypeDefaultDescription
--no-lingerboolfalse(linux) skip the systemd user-linger consent prompt; worker becomes session-bound
--non-interactiveboolfalsenever prompt; on linux equivalent to --no-linger; on macOS has no effect

Exit codes

CodeMeaning
0Worker installed; supervisor running or present.
1Failure — unsupported OS (Windows), name validation, server error, supervisor bootstrap failure, or non-recoverable linger error.

If supervisor bootstrap fails partway, the CLI tells you whether to re-run worker install (idempotent) or worker uninstall <name> to roll back.


list

List workers in the active team context, merging server-side records with local config so you can see divergence at a glance.

Synopsis

justtunnel worker list [flags]

Examples

List active workers

justtunnel worker list
Workers in team:acme:
NAME           ID         SUBDOMAIN          STATUS  PRESENCE
staging-api    wrk_abc1   staging-api--acme  active  synced
build-runner   wrk_def2   build-runner--acme active  synced
prod-webhooks  -          -                  -       local-only

PRESENCE is one of synced, server-only (no local config — typically a teammate's worker), or local-only (local config that the server doesn't know about).

Include quarantined workers

justtunnel worker list --all

Soft-deleted workers stay listed for 30 days before the server reaper removes them. --all shows them so you can spot a recent worker rm that didn't fully clean up.

Flags

FlagTypeDefaultDescription
--allboolfalseinclude quarantined workers (soft-deleted; permanently removed after 30 days)

Exit codes

CodeMeaning
0Listed successfully.
1Failure — not signed in, not a team context, or the server returned an error.

start

Run the worker WebSocket attach loop in the foreground. This is the same code path the supervisor uses; invoke it directly to debug a worker or to wire it into your own process supervisor.

Synopsis

justtunnel worker start <name>

The command blocks until SIGINT/SIGTERM, or until the server closes the session with a terminal status (suspended, already attached elsewhere, etc.).

Examples

Start a worker in the foreground

justtunnel worker start staging-api

Logs stream to stderr. Press Ctrl-C for a clean shutdown:

worker starting  worker=staging-api  context=team:acme  subdomain=staging-api--acme

Run under your own supervisor

# in a systemd unit, an init script, or `tmux` session:
exec justtunnel worker start staging-api

start does not write to the per-worker log file when invoked directly — that path is owned by the platform supervisor. Running it under your own supervisor means logs go wherever your supervisor captures stderr.

Flags

No flags.

Exit codes

CodeMeaning
0Stopped cleanly via SIGINT/SIGTERM.
1Failure — not signed in, no local config (run `worker create` first), server rejected the session (403/401), or any other runtime error.

A 403 here usually means the worker was created with worker create but never installed; run worker install <name> to provision a service token, or wait for the team's quota / suspension state to resolve.


status

Show server-side and local supervisor status for workers in the active team context.

Synopsis

justtunnel worker status [name]

Without name, prints a table of every worker. With name, prints a verbose key:value detail view for one worker.

Examples

List all workers with status

justtunnel worker status
Workers in team:acme:
NAME          SERVER  LOCAL              LAST SEEN
staging-api   active  launchd:running    2026-05-06 12:34:56Z
build-runner  active  systemd:stopped    2026-05-05 09:01:22Z
ad-hoc-debug  <local-only>  none         -

LOCAL reflects what the platform supervisor reports. none means the worker isn't managed by a supervisor (foreground-only via worker start).

Verbose detail for a single worker

justtunnel worker status staging-api
Worker:    staging-api
Context:   team:acme
Server:    active
Local:     launchd:running
Last Seen: 2026-05-06 12:34:56Z

Flags

No flags.

Exit codes

CodeMeaning
0Status printed.
1Failure — not signed in, not a team context, server error, or the named worker was not found.

logs

Show logs for a worker tunnel. Reads ~/.justtunnel/logs/worker-<name>.log written by the platform supervisor.

Synopsis

justtunnel worker logs <name> [flags]

Default mode prints the last 1000 lines of the active log file. Daily rotation and retention (7 days, 100 MB cap) are enforced by the writer side; this command never deletes log files.

Examples

Tail the last 100 lines

justtunnel worker logs staging-api -n 100

The --lines value is capped at 100,000 to protect against typos.

Follow the active log file in real time

justtunnel worker logs staging-api -f

Tails the active file and keeps reading after the daily rotation. Press Ctrl-C to exit.

justtunnel worker logs staging-api --all

Concatenates every retained log file in chronological order. Useful when you don't know which day a problem started.

Flags

FlagTypeDefaultDescription
--allboolfalseprint all retained log files in chronological order
-f, --followboolfalsetail the active log file; exit on Ctrl-C
-n, --lines <int>int1000number of trailing lines to print from the active file

Exit codes

CodeMeaning
0Logs printed, or follow mode exited cleanly.
1Failure — no log file exists (worker has never been started), unreadable file, or follow-mode read error.

rm

Remove a worker. By default, only the local config is removed — server-side state is left alone unless you pass --delete-on-server.

Synopsis

justtunnel worker rm <name> [flags]

The local-only default lets you clean up stale config even if you've lost team membership. --delete-on-server is the right tool when you want the worker gone for real.

Examples

Local-only cleanup (default)

justtunnel worker rm staging-api
Removed local config for "staging-api". The worker may still be registered server-side.
Use --delete-on-server to also delete server-side.

Delete server-side too

justtunnel worker rm staging-api --delete-on-server
Quarantined worker "staging-api" (local config removed; permanent server-side removal in 30 days).

The server soft-deletes for 30 days. Run worker list --all if you need to confirm the row is in quarantine.

Flags

FlagTypeDefaultDescription
--delete-on-serverboolfalsealso delete the worker server-side (off by default; local-only removal is the safe default)

Exit codes

CodeMeaning
0Removed (including the no-op case where there was nothing to remove).
1Failure — server refused the delete, local-write error, or you lack permission.

rm does NOT stop a managed service supervisor. If the worker was installed with install, use uninstall instead to also tear down the supervisor.


uninstall

Reverse worker install: stop the platform service, remove the local service definition, and delete the local worker config. Optionally also delete the server-side record.

Synopsis

justtunnel worker uninstall <name> [flags]

Idempotent — re-running on an already-uninstalled worker is a no-op.

Examples

Tear down a worker

justtunnel worker uninstall staging-api
Uninstalled worker "staging-api"

By default, the server-side record is preserved. Pair with --delete-on-server to also delete it.

Tear down everything, including server state

justtunnel worker uninstall staging-api --delete-on-server
Uninstalled worker "staging-api" (server-side row quarantined; permanent removal in 30 days)

When --delete-on-server is set, the server delete runs FIRST so a 403 leaves your local state intact and recoverable.

Best-effort cleanup of a corrupted install

justtunnel worker uninstall staging-api --force

--force continues past per-step failures and prints warnings to stderr instead of aborting. Useful when local config is corrupt or the supervisor is in a wedged state — the command exits 0 and you get a summary of what failed.

Flags

FlagTypeDefaultDescription
--delete-on-serverboolfalsealso delete the server-side worker record (off by default)
--forceboolfalsecontinue past per-step failures and print warnings to stderr (best-effort cleanup)

Exit codes

CodeMeaning
0Uninstalled, already uninstalled (no-op), or completed under --force with warnings.
1Failure — unsupported OS (Windows; use `worker rm` instead), server-side delete failed without --force, or a step failure without --force.

See also