Quick start
Run untrusted code in a hardened Docker container, get back the exit code, logs, and any files the container produced. That is the whole library.
Install
npm install light-runnerRequirements:
- Node.js >= 22
- A running Docker daemon (Docker Desktop on macOS / Windows,
dockerdon Linux) - Optional: gVisor for kernel-level isolation
Run something
import { DockerRunner } from 'light-runner';
const runner = new DockerRunner({ memory: '512m', cpus: '1' });
const execution = runner.run({
image: 'python:3.12-alpine',
entrypoint: 'python main.py',
dir: './my-project',
input: { task: 'compute', n: 20 },
timeout: 30_000,
extract: [{ from: '/app/result.json', to: './out' }],
});
const result = await execution.result;
result.success // true if exitCode === 0, not cancelled, not timed out
result.exitCode // container exit code
result.duration // ms
result.cancelled // true if cancel() / signal aborted
result.extracted // [{ from, to, status, bytes? }, ...] if extract was setWhat happens under the hood
- A named Docker volume is created (
light-runner-<uuid>). - The folder at
diris streamed into the volume via a throwaway Alpine seeder, skipping.git,node_modules,dist,build,.next,.cache,.turbo,coverage, and all symlinks. - Your image runs with the volume mounted at
workdir(default/app), strict isolation flags, and a PID / memory / CPU cap. - On exit-code 0, each
extractentry is streamed out viatar. On non-zero exit, extract is skipped. - The volume is destroyed, success or not.
Where to go next
- Extract files — how to pull artifacts out of the container after a run
- Detached runs — long-running jobs that survive a host restart
- Security model — what the sandbox protects against and what it does not
- gVisor & Kata — adding a stronger runtime for hostile code
- API reference — full type signatures and class methods