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 contextstart— run the worker attach loop in the foregroundstatus— show server-side and local supervisor statelogs— read or tail per-worker logsrm— remove a worker (local-only by default)uninstall— uninstall the managed service and tear down
Platform support
| Platform | Foreground (worker start) | Managed service (worker install) |
|---|---|---|
| macOS | Supported | Supported (launchd-user) |
| Linux | Supported | Supported (systemd-user) |
| Windows | Supported | Not 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
| Code | Meaning |
|---|---|
| 0 | Worker created server-side and local config written. |
| 1 | Failure — 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
| Flag | Type | Default | Description |
|---|---|---|---|
| --no-linger | bool | false | (linux) skip the systemd user-linger consent prompt; worker becomes session-bound |
| --non-interactive | bool | false | never prompt; on linux equivalent to --no-linger; on macOS has no effect |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Worker installed; supervisor running or present. |
| 1 | Failure — 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
| Flag | Type | Default | Description |
|---|---|---|---|
| --all | bool | false | include quarantined workers (soft-deleted; permanently removed after 30 days) |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Listed successfully. |
| 1 | Failure — 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
| Code | Meaning |
|---|---|
| 0 | Stopped cleanly via SIGINT/SIGTERM. |
| 1 | Failure — 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
| Code | Meaning |
|---|---|
| 0 | Status printed. |
| 1 | Failure — 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.
Print every retained day, oldest first
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
| Flag | Type | Default | Description |
|---|---|---|---|
| --all | bool | false | print all retained log files in chronological order |
| -f, --follow | bool | false | tail the active log file; exit on Ctrl-C |
| -n, --lines <int> | int | 1000 | number of trailing lines to print from the active file |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Logs printed, or follow mode exited cleanly. |
| 1 | Failure — 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
| Flag | Type | Default | Description |
|---|---|---|---|
| --delete-on-server | bool | false | also delete the worker server-side (off by default; local-only removal is the safe default) |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Removed (including the no-op case where there was nothing to remove). |
| 1 | Failure — 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
| Flag | Type | Default | Description |
|---|---|---|---|
| --delete-on-server | bool | false | also delete the server-side worker record (off by default) |
| --force | bool | false | continue past per-step failures and print warnings to stderr (best-effort cleanup) |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Uninstalled, already uninstalled (no-op), or completed under --force with warnings. |
| 1 | Failure — unsupported OS (Windows; use `worker rm` instead), server-side delete failed without --force, or a step failure without --force. |
See also
justtunnel context— switch into a team context before running worker commands.justtunnel auth— sign in before running worker commands.- Run a worker tunnel — task-oriented walkthrough.
- Worker tunnels — concept doc explaining how workers differ from ad-hoc tunnels.
- Worker won't start — troubleshooting guide.