Skip to main content
Jeremias Meister - Tools & Pipeline

Docker Runner

The Succession Runner is a Docker image that executes your pipeline graphs on any machine with Docker — a build server, a NAS, a render farm node, a cloud VM, or a CI pipeline. You design graphs in the desktop app as usual, then run them headless wherever you need them.

Requires a Business plan or higher.

What You Need

  1. Docker installed on the machine that will run the graph (Docker Desktop on Windows/macOS, Docker Engine on Linux)
  2. A License Token created in the desktop app (see below)
  3. A graph file (.json) exported from your project

Getting the Image

Download succession-runner.tar.gz from the releases page — it is listed as a release asset alongside the desktop installers. Load it into Docker once:

docker load < succession-runner.tar.gz

After loading, docker images lists it as succession-runner.

License Tokens

The runner does not use your account login. Instead it authenticates with a License Token — a scoped credential that can only validate your license, nothing else. If a token ever leaks, you revoke that one token and your account, your login, and your other tokens stay untouched.

To create one:

  1. Open the desktop app and go to Licensing (avatar menu)
  2. In the License Tokens section, enter a name (for example render-server) and pick a lifetime
  3. Click generate. The token (starting with lt_) is shown once — copy it now and store it somewhere safe, for example your CI secret store

You can see every token’s creation date, expiry, and last use in the same section, and revoke any of them at any time. A revoked token is refused for new container starts and graph deployments within a few minutes. A container already running in sidecar mode will continue until it is restarted — the service does not re-check the token at runtime.

Use one token per machine or pipeline. If a server is decommissioned or a token leaks, you can revoke exactly that one.

Running a Graph

The container runs indefinitely: your graph stays deployed and its triggers keep firing — file watchers watch, cron schedules fire, webhooks listen. This is the right mode for anything long-running.

docker run -d --name my-pipeline \
  -v /path/to/project:/workspace \
  -e SUCCESSION_LICENSE_TOKEN=lt_... \
  -e SUCCESSION_GRAPH=my-graph.json \
  -e SUCCESSION_TIMEOUT=0 \
  succession-runner

Stop it like any container:

docker stop my-pipeline

The graph is stopped cleanly before the container exits.

One-Shot Mode

Without SUCCESSION_TIMEOUT=0, the container deploys the graph and then polls the service health endpoint until two consecutive polls show no active workflows, or until SUCCESSION_TIMEOUT seconds elapse.

What this does and does not guarantee. Exit code 0 means the graph deployed successfully and the service stayed healthy during the settle window. It does NOT mean the graph ran to completion or that a trigger ever fired — the engine does not yet report per-graph execution state, so the poll loop reads global health counters only. A graph whose trigger fires after 30 seconds will produce exit 0 at around 8 seconds of settle with no work done.

Use one-shot mode only for graphs you are confident fire immediately and finish in a few seconds. For anything longer, for time-based triggers, or for any graph whose completion you need to verify, use sidecar mode and check your output artefacts directly.

docker run --rm \
  -v /path/to/project:/workspace \
  -e SUCCESSION_LICENSE_TOKEN=lt_... \
  -e SUCCESSION_GRAPH=my-graph.json \
  succession-runner

With Docker Compose

For a permanent deployment, a compose file keeps the configuration in one place and restarts the runner with the host:

services:
  succession:
    image: succession-runner
    restart: unless-stopped
    volumes:
      - ./project:/workspace
    environment:
      SUCCESSION_GRAPH: my-graph.json
      SUCCESSION_TIMEOUT: "0"
    env_file:
      - succession.env   # holds SUCCESSION_LICENSE_TOKEN and secrets

Environment Variables

VariableRequiredDefaultPurpose
SUCCESSION_LICENSE_TOKENyes—License Token from the desktop app (lt_...)
SUCCESSION_GRAPHyes—Path to the graph .json, relative to the workspace (or absolute)
SUCCESSION_WORKSPACEno/workspaceWhere your mounted project lives inside the container
SUCCESSION_TIMEOUTno600One-shot mode: max seconds to wait. 0 = sidecar mode, run until stopped
SUCCESSION_SECRET_<NAME>no—Injects a secret into the graph (see below)
SUCCESSION_API_TOKENnoauto-generatedInternal service credential; set it only if an external tool must call the runner’s API

Secrets

Graphs reference secrets as @secret.NAME (see Parameter Scripting). In the runner, secrets come from environment variables with the SUCCESSION_SECRET_ prefix:

docker run -d \
  -e SUCCESSION_SECRET_SLACK_WEBHOOK=https://hooks.slack.com/... \
  ...

makes @secret.SLACK_WEBHOOK available inside the graph.

Handling secrets safely:

  • Prefer --env-file (or compose env_file) over -e on the command line, so tokens and secrets don’t end up in shell history or CI logs
  • Environment values are visible to anyone who can run docker inspect on the host — treat host access as secret access
  • Any script-executing node in a graph can read all injected secrets, not only the ones it references. Only run graphs you trust with the secrets you provide

File Access

The runner can only read and write inside the mounted workspace (and the container’s temporary directory). A graph cannot touch other paths, even if a node is configured with one — the same filesystem access policy you know from the desktop app, locked to the workspace.

Practical consequence: use paths under /workspace/... in your graph’s file nodes, and mount everything the graph needs into the workspace.

Trust caveat: script-executing nodes (Run Script, Execute Command, etc.) spawn subprocesses outside the file access policy — they can read and write any path the container user can reach, not just the workspace. They also inherit the full process environment, including SUCCESSION_LICENSE_TOKEN and the internal SUCCESSION_API_TOKEN — an untrusted graph can read and exfiltrate these values. License tokens are revocable and validation-only, but treat them as you would any credential. Only run graphs you trust with the access and credentials you provide.

Webhooks and External Access

A webhook trigger listens on its own Port, not on the service port. Set its Bind IP to 0.0.0.0 so it accepts connections from outside the container, then publish that port when starting the container:

docker run -d \
  -p 8080:8080 \
  -e SUCCESSION_GRAPH=my-graph.json \
  -e SUCCESSION_TIMEOUT=0 \
  -v "$PWD":/workspace \
  succession-runner

A trigger with Port 8080 and Webhook Path /build is then reachable at http://<host>:8080/build. Webhook triggers that set the same Bind IP and port share it, so one published port serves all of them as long as their paths differ.

Exit Codes

CodeMeaning
0One-shot: graph deployed and ran. Sidecar: stopped cleanly
1Graph reported an error in the health-check response (rare — the engine does not yet update this field per graph after deploy; will become more common when per-graph execution tracking lands)
2Invalid input: graph file not found, or a bad environment value
3The Succession service failed to start or stopped unexpectedly
4Graph deployment failed — check the license token and the graph file
124One-shot mode timed out

Viewing Logs

docker logs my-pipeline

Service and node execution logs are printed at info level. To change verbosity, set -e RUST_LOG=debug (or warn) when starting the container.

Limitations

  • No DCC integrations — nodes that drive Blender, Maya, Houdini, Unreal, Unity, Photoshop, or Substance need those desktop applications and are not available in a Linux container
  • Custom Python nodes are not supported by the runner yet (they are disabled in the container configuration)
  • One graph per container. Run several containers for several graphs — they don’t interfere with each other

Troubleshooting

“Graph deployment failed (check license token and graph file)” The license token is missing, mistyped, expired, or revoked — or the graph file is not valid. Check docker logs for the specific license error, and verify the token in the desktop app’s Licensing section.

“Graph file not found” The path in SUCCESSION_GRAPH doesn’t exist inside the container. Remember it resolves relative to the workspace: -v /my/project:/workspace plus SUCCESSION_GRAPH=graphs/build.json expects /my/project/graphs/build.json on the host.

Graph runs but files don’t appear Check the node writes under /workspace/... — writes outside the workspace are blocked by the file access policy (look for access-denied entries in the logs).