Skip to main content

Self-hosted execution runner for IceFold nodes (reverse-connects to an IceFold server, like a self-hosted CI runner).

Project description

icefold-runner

A self-hosted execution runner for IceFold nodes — like a GitHub self-hosted CI runner. You start it on your own machine; it reverse-connects to an IceFold server (so it works behind NAT with no inbound ports, no public IP, no tunnel), receives node-execution jobs, runs them locally, and streams results back.

It is the place where your uploaded node code runs — on your hardware, with full subprocess / ffmpeg / GPU / any-dependency access — instead of inside the server's restricted sandbox.

How it works

   your machine (private, behind NAT)              IceFold server (public)
 ┌──────────────────────────────────┐  reverse WSS  ┌───────────────────────────┐
 │ icefold-runner                    │ ───────────► │ /v1/ws/worker?token         │
 │  • dials out, token auth          │  node_exec ◄─│ routes node runs (per user) │
 │  • reconnect + keepalive          │  node_done ─►│                             │
 │  • bundle runner:                 │              │                             │
 │    GET /v1/bundles/<hash>         │   HTTP pull  │ /upload  /download          │
 │    import bundle + preflight deps │ ◄──────────► │ /v1/workers/output          │
 │    await __icefold_run__          │              │                             │
 └──────────────────────────────────┘   HTTP push  └───────────────────────────┘
  • Control plane rides the reverse WebSocket (node_exec / cancelnode_status / node_done / missing_dep), JSON frames XOR-obfuscated with the token (TLS still does the real protection). Each node_exec frame only carries a bundle_hash and a single already-sliced variant — no source.
  • Bulk media + bundles ride plain HTTP: the runner GETs inputs from the server's /upload & /download and node bundles from /v1/bundles/<hash> (sha256-addressed, cached locally as runner_work_dir/bundles/<hash>.py, re-hashed on every download), runs the bundle, POSTs products back to /v1/workers/output (which returns server-canonical paths).
  • The runner ships no node implementations and never compiles user source. The IceFold server renders every node (your custom ones and the platform's built-in ones) into a self-contained .py bundle, with python_deps / binary_deps declared in the bundle header. The runner imports the bundle, pre-flights the deps (sending back a structured missing_dep reply with platform-aware install hints if anything is absent), and awaits __icefold_run__(inputs, ctx_dict). So when the server adds or upgrades nodes, you never have to upgrade the runner.
  • Variant planning / dimension & provider resolution all stay on the server; each job is a single already-sliced leaf call.

Install

Requires only Python ≥ 3.11 (it pulls in icefold-sdk).

The runner itself ships no node tooling. A node declares what it needs in its bundle header — binary_deps (e.g. ffmpeg / ffprobe on PATH for media nodes) and python_deps (whatever your custom nodes import) — and the runner pre-flights those before each run, replying with a platform-aware install hint (missing_dep) for anything absent. So you install a node's dependencies only when you actually run a job that needs them, and the runner tells you exactly what to install.

pip install icefold-runner          # pulls in icefold-sdk

From source:

git clone <this-repo> icefold-runner
cd icefold-runner
python -m venv .venv && . .venv/bin/activate
pip install -e .

Run

Generate a token in the IceFold app (Nodes ▸ Connect a runner), then:

icefold-runner --token <your-token>

That's it — the token (GitHub-CI style) encodes + signs your IceFold user id, so there's no server URL or user id to pass. The server is built in.

Every flag also reads an env var:

flag env meaning
--token ICEFOLD_RUNNER_TOKEN runner token from the IceFold app
--runner-id ICEFOLD_RUNNER_ID stable id (default: hostname)
--work-dir ICEFOLD_RUNNER_DIR scratch for staged inputs + products

The runner honors standard proxy env vars (HTTPS_PROXY, …) for reaching the server. It reconnects automatically with backoff; an auth rejection is fatal.

Self-hosting / dev: point the runner at a different server with the ICEFOLD_RUNNER_SERVER env var (e.g. ws://127.0.0.1:7000).

Layout

icefold_runner/      the runner agent (connection, file staging, bundle exec)
  client.py            reverse-WS client: dial / auth / reconnect / keepalive
  runner.py            fetch /v1/bundles/<hash>, preflight deps, await __icefold_run__
  __main__.py          CLI entrypoint (icefold-runner)

The runner imports the bundle on demand; the bundle is self-contained and already inlines whatever it needs (the author's function body, the Inputs / Output dataclasses, and a minimal NodeContext shim). The only runtime dependency on icefold-sdk is the wire protocol + a small helper kit (get_file_id / run_blocking / write_text), used by the runner agent itself, not by node code.

Security model

  • Node code runs unsandboxed here — it's your machine, your risk. That's the point: code the server sandbox forbids (subprocess/ffmpeg/native deps) runs on the runner instead. The runner downloads each bundle from the server and executes it; it verifies the bundle's sha256 matches the requested hash, but the bundle itself is whatever the server you authenticated to sends. Only point a runner at a server you trust.
  • The runner only talks to the one server you point it at, authenticated by the shared token; it pulls input files and pushes products over HTTP to that host.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

icefold_runner-0.1.8.tar.gz (23.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

icefold_runner-0.1.8-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file icefold_runner-0.1.8.tar.gz.

File metadata

  • Download URL: icefold_runner-0.1.8.tar.gz
  • Upload date:
  • Size: 23.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for icefold_runner-0.1.8.tar.gz
Algorithm Hash digest
SHA256 13faa41c1fa03d826cfde0a40aece56ca11245f132b7842820bb7d295ea73575
MD5 e887b1344e6f2e7ceba5205657e61633
BLAKE2b-256 d271fdc49f4c3f1e7d81f6a30c98b5d24d48b2e8976a2cc90be4e892f8acf4ce

See more details on using hashes here.

File details

Details for the file icefold_runner-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: icefold_runner-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for icefold_runner-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 80aed260613f1f6080a9870df1e7f8c7b1127e5eee1fa5a8f4d931eea2f42742
MD5 6ab509c0c8817194ccbbe25bb9de10fc
BLAKE2b-256 e4f5ca1a004e6b34c88ee877e82d7408fb2d1a00acd6cf14548bd37961547e7d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page