Processes
Run one-off commands, background servers, and interactive shells inside a sandbox — and manage them long after the client disconnects.
A process is a command running inside a sandbox. Tektona runs and tracks
processes for you: start one, walk away, and come back later to fetch its exit
code, tail its logs, or stop it. Processes are sandbox-owned — a dropped
connection never kills them; the sandbox owns their lifetime — and reachable
from the CLI, the HTTP API, the TypeScript SDK, and, from inside the sandbox,
tektonactl.
Every surface acts on the same set of processes, so a background server an agent
starts with tektonactl process run shows up in tektona sandbox process ls
and can be stopped or tailed from outside — and vice versa.
Process state lives in the sandbox. Running processes and their output survive
pause/resume. Finished-process records and logs also survive a reboot, a
disk-only suspend, and crash recovery — bounded to roughly the 200 most-recent
processes. A process still running when the sandbox goes down comes back
recorded as interrupted (finish_reason=interrupted) with whatever output
it had produced. Deleting the sandbox removes everything — there is no durable
archive, so capture what you need before deleting.
Run a one-off command
run executes a command and streams its output to your terminal, exiting with
the command's own exit code:
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX -- npm testEverything after -- is the command. run waits by default; local stdin is
piped through when the process isn't a TTY. The remote exit code becomes the
CLI's exit code, so run drops straight into a script or CI step. A process
that was killed instead of exiting cleanly still reports non-zero: 128 + signal
for a signal (SIGKILL → 137), 124 for a --timeout kill.
The command is an argument vector, not a shell line — &&, pipes, and globs
are not interpreted. For a shell one-liner, pass -s/--shell to run it through
a shell inside the sandbox (bash when the image has it, sh otherwise):
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX -s -- 'apt update && apt install -y nginx'The SDKs' process.run() takes a shell command line already, so they need no
equivalent flag.
Set the environment, working directory, and run-as user inline:
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX \
--env NODE_ENV=production --env PORT=8080 \
--cwd /workspace --user dev \
-- npm run build--env is repeatable. --user defaults to the image's default user; it is a
convenience, not a security boundary (root is allowed — same trust model as SSH
into your own sandbox).
Kill a runaway command with --timeout (a Go-style duration; sub-second values
round up to the 1s minimum). On expiry the whole process group is killed and the
result is recorded as timed-out:
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX --timeout 10m -- ./slow-job.shStart a background process
--detach (-d) starts a process and returns immediately, printing its id.
Give it a --name (short: -n) to address it later without copying the ULID
around:
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX -d --name dev-server -- npm run devA name is [a-z0-9_-], must start and end alphanumeric, and is unique among
running processes (starting a second dev-server while the first runs is a
conflict). A name resolves to its running holder, or — if none is running — to
the most-recent finished process with that name; a ULID always resolves to its
exact record. So get/logs <name> keep working after the process finishes.
If you don't pass --name, a memorable one is generated for you (like
quantum-phoenix), so every process is addressable by something friendlier than
its ULID.
List, inspect, and stop by name or ULID:
tektona sandbox process ls 01J9F3ZK7QW4B2Y8N5T1QAZ6RX
tektona sandbox process get 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server
tektona sandbox process stop 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-serverls shows running process instances newest first and hides finished ones (a
footer notes how many). An AUTOSTART column shows * for autostart-managed
instances. Add -a/--all to also show finished instances after a blank line,
or --autostart to list the autostart definitions themselves.
Interactive shells
Pass --tty (-t) to allocate a real PTY. run puts your terminal into raw
mode and forwards keystrokes, resize events, and Ctrl-C to the remote process:
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX -t -- bashStart an interactive process detached and reconnect to it later with attach.
Attach replays a screenful of recent output, then streams live; multiple clients
can attach to the same process at once:
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX -d -t --name repl -- python
tektona sandbox process attach 01J9F3ZK7QW4B2Y8N5T1QAZ6RX replDetaching from attach never stops the process — it keeps running. (Ctrl-C is
forwarded to the process; close the connection to leave.)
Logs
Every non-TTY process keeps stdout and stderr separated in a capped, disk-backed log store inside the sandbox. Fetch the buffered log, or tail it live:
tektona sandbox process logs 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server # buffered
tektona sandbox process logs 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server -f # follow
tektona sandbox process logs 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server --tail 100 # last 100 lineslogs -f tails until the process ends; Ctrl-C stops tailing without touching
the process. The store is capped per process (--max-log-bytes, default 128
MiB); old output is evicted once the cap is reached. Pass --max-log-bytes 0 at
start time to disable logging entirely and save disk — logs then can't be
fetched or followed for that process, though you can still attach.
Stop and signal
stop escalates gracefully: SIGTERM, a grace period, then SIGKILL, delivered to
the whole process group. --force skips straight to SIGKILL:
tektona sandbox process stop 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server
tektona sandbox process stop 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server --forceTo deliver one specific signal instead of stopping, use signal:
tektona sandbox process signal 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server SIGHUPSignals are delivered to the process group and accepted from this set (with or
without the SIG prefix): SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGKILL,
SIGUSR1, SIGUSR2, SIGSTOP, SIGCONT. Terminal resizing is not a signal —
it goes through attach.
Keep the sandbox awake
A sandbox auto-pauses after a period without boundary-crossing traffic (see
Sandbox lifecycle). A silent in-VM process — a build, a
long test run — looks idle and can get paused mid-work. Pin the sandbox awake
for the process's lifetime with --prevent-auto-pause:
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX --prevent-auto-pause -- ./train.shWhile a pinned process runs, the sandbox counts as active and is exempt from auto-pause. It defaults off, so a forgotten daemon can't silently defeat auto-pause; once the process exits, the idle timer resumes.
What happens when the sandbox pauses
A hibernate pause snapshots the sandbox's RAM, so processes survive the pause
in memory. --on-hibernate controls what happens to each process across a
hibernate pause:
| Value | Behavior |
|---|---|
preserve (default) | Preserved intact in the RAM snapshot; continues after resume. Re-tail the logs after resume to keep following. |
stop | Gracefully stopped (TERM→grace→KILL) just before the snapshot and finalized. |
restart_after_resume | Kept running into the RAM snapshot, then stopped and re-executed fresh once the guest resumes — same name and command, new ULID, linked back to its predecessor. For servers whose connections die during a pause. |
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX \
-d --name dev-server --on-hibernate restart_after_resume -- npm run dev--on-hibernate applies only to a hibernate pause. A suspend pause instead
persists only the disk, so the guest cold-boots on resume and every process is
gone regardless of --on-hibernate — a process comes back only if it was started
with --autostart (see below).
Autostart on every boot
--autostart persists the process definition to the sandbox disk and
relaunches it (fresh process, same name) on every boot — after a stop/start,
reboot, crash recovery, or a filesystem-fork child's first boot. It requires
--name and captures the full spec (command, env, cwd, user, tty, on-hibernate,
prevent-auto-pause, log cap).
tektona sandbox process run 01J9F3ZK7QW4B2Y8N5T1QAZ6RX \
-d --name dev-server --autostart -- npm run devThe definition outlives its instances: stopping the running process does not remove it — the process comes back next boot. List the persisted definitions, each with its last launch outcome, to answer "did my autostarts come up?":
tektona sandbox process ls 01J9F3ZK7QW4B2Y8N5T1QAZ6RX --autostartDisabling is explicit and sticks:
tektona sandbox process autostart 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server off
tektona sandbox process autostart 01J9F3ZK7QW4B2Y8N5T1QAZ6RX dev-server onAutostart doesn't apply on hibernate resume (the RAM is restored, so
--on-hibernate governs there) — only on a fresh boot.
Paused sandboxes
Every process operation except run (which always wakes the sandbox to run your
command) returns a conflict on a paused sandbox, so a status check never silently
costs you a resume. Pass --resume to wake it and serve the request:
tektona sandbox process ls 01J9F3ZK7QW4B2Y8N5T1QAZ6RX --resumeFrom inside the sandbox
Agents and scripts running inside a sandbox use tektonactl process, which
takes no sandbox id — it targets its own sandbox — and runs the same commands:
tektonactl process run -d --name dev-server -- npm run dev
tektonactl process ls
tektonactl process logs dev-server -f
tektonactl process stop dev-serverThis is the primary way an in-sandbox agent runs background work. From outside,
wrap it over SSH — tektona ssh <id> -- tektonactl process ls — or use the
tektona sandbox process commands above against the same processes.
See also
- CLI reference:
sandbox process - TypeScript SDK: processes
- Process streaming protocol — the raw WebSocket wire format
- Sandbox lifecycle — auto-pause and how
--prevent-auto-pauseinteracts with it