light-process

Execution (light-run)

light-process no longer talks to Docker directly. Every node runs inside a container spawned by the light-run HTTP service.

light-processDAG orchestrator - evaluates the graphlight-runHTTP wrapper - POST /run, serves artifactslight-runnerDocker SDK - dockerode, extract, stateDockerisolation boundary - the container runs hererequestPOST /runresultRunState
Fig. - one request, three layers, one isolation boundary.no upward coupling

Configuration

light-process runs in one of two modes:

  • All-in-one (default): leave LIGHT_RUN_URL unset. light run / light serve start 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 auth

Or 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 fieldlight-run fieldNotes
imageimageRequired
filesfilesRecord<path, content>, paths relative, >= 1 entry
entrypointentrypointExecuted via sh -c
setupsetupCommands chained with && before entrypoint
timeouttimeoutOmitted when 0 (light-runner default applies)
networksnetworksArray of network names; first is primary, rest connected after creation; [] = light-run default
workdirworkdirOmitted when /app (light-run default)
env (names)env (name->value)Values resolved from the light-process env
runtime inputinputPiped to container stdin
-extractAlways [<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 doctor

In 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.

On this page