Execution (light-run)
light-process no longer talks to Docker directly. Every node runs inside a container spawned by the light-run HTTP service.
Configuration
light-process runs in one of two modes:
- All-in-one (default): leave
LIGHT_RUN_URLunset.light run/light servestart a local light-run for you on a free port - nothing to export. - Explicit runner: point at a light-run you started yourself (a remote or shared instance).
# Explicit runner only - skip this entirely in all-in-one mode:
export LIGHT_RUN_URL=http://localhost:3001 # required ONLY in this mode
export LIGHT_RUN_TOKEN=your-bearer-token # optional, if that light-run needs authOr programmatically via the SDK:
import { LightRunClient } from 'light-process';
const runner = new LightRunClient({
url: 'http://localhost:3001',
token: process.env.LIGHT_RUN_TOKEN,
});Node -> light-run mapping
Each node field is forwarded to POST /run:
| Node field | light-run field | Notes |
|---|---|---|
image | image | Required |
files | files | Record<path, content>, paths relative, >= 1 entry |
entrypoint | entrypoint | Executed via sh -c |
setup | setup | Commands chained with && before entrypoint |
timeout | timeout | Omitted when 0 (light-runner default applies) |
networks | networks | Array of network names; first is primary, rest connected after creation; [] = light-run default |
workdir | workdir | Omitted when /app (light-run default) |
env (names) | env (name->value) | Values resolved from the light-process env |
| runtime input | input | Piped to container stdin |
| - | extract | Always [<workdir>/.lp-output.json] |
Output channel
A node writes its result to .lp-output.json in its workdir. light-process fetches the artifact via GET /runs/:id/artifacts/.lp-output.json once the run succeeds. Empty or non-object output becomes {}.
Run-scoped networks
A workflow's networkDefs are provisioned through light-run's network API, not the /run body: the executor calls POST /networks before the DAG and DELETE /networks/:name after. Node networks entries that match a networkDef alias are rewritten to the run-scoped name (lp-<runId>-<alias>) at run time. See workflows.md.
Services (sidecars)
A workflow's services are started detached (light-run POST /run with detached: true) before the DAG and stopped (POST /runs/:id/stop) after it, before networks are deleted. The service's light-run id is its container hostname; node providesEnv values resolve ${service:<id>} to that hostname, so a workload reaches a proxy without holding its secret. See workflows.md.
Isolation
Capability drops, PID limits, isolated bridge networks, gVisor/runsc runtime, GPU access, memory/CPU caps - all handled by light-run (which delegates to light-runner). Configure them on the light-run instance, not here. See the light-run README.
Cancellation
Workflows support cancellation via AbortController. When aborted, light-process calls POST /runs/:id/cancel on light-run.
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
const result = await wf.execute(input, {
runner,
signal: controller.signal,
});Health check
light doctorIn all-in-one mode it confirms the light-run binary is installed (so light serve can spawn it). When LIGHT_RUN_URL is set, it pings that instance's GET /health instead.