Skip to content

Runners

Runners are worker machines that execute custom scripts from your workflows. SuperPlane provides components for executing shell commands, bash scripts, JavaScript, and Python scripts.

Use runner components when a workflow step needs code or shell that SuperPlane integrations do not cover:

  • Run build scripts, linters, or custom tooling on dedicated machines
  • Transform upstream payload data with JavaScript or Python and pass structured output downstream
  • Execute in a specific container image without managing SSH or long-lived hosts
  • Provide sandboxed compute for coding agents and AI workflows

For remote commands on a host you manage directly, consider SSH Command instead. For HTTP or API calls, use HTTP Request.

Runs shell commands on a runner machine. Commands execute in order. The task succeeds when the last command exits with code 0, or fails if any command exits with a non-zero code.

Example:

Terminal window
git clone https://github.com/example/repo.git
cd repo
docker build -t example-image .
docker push example-image

To pass output from the commands to the next node on the canvas, write valid JSON to the $SUPERPLANE_RESULT_FILE file — the path the runner sets for your task.

Terminal window
git clone https://github.com/example/repo.git
cd repo
export IMAGE_TAG=example-image-$(git rev-parse HEAD)
docker build -t $IMAGE_TAG .
docker push $IMAGE_TAG
echo "{\"image\": \"$IMAGE_TAG\"}" > $SUPERPLANE_RESULT_FILE

Runs a Bash script on a runner machine. The task succeeds when the script exits with code 0, or fails if the script exits with a non-zero code.

Example:

#!/bin/bash
set -euo pipefail
for i in {1..10}; do
echo "Hello, world! $i"
done

To pass output from the script to the next node on the canvas, write valid JSON to the $SUPERPLANE_RESULT_FILE file — the path the runner sets for your task.

#!/bin/bash
set -euo pipefail
git clone https://github.com/example/repo.git
cd repo
docker build -t example-image .
docker push example-image
export IMAGE_TAG=example-image-$(git rev-parse HEAD)
docker build -t $IMAGE_TAG .
docker push $IMAGE_TAG
echo "{\"message\":\"Hello, world!\"}" > $SUPERPLANE_RESULT_FILE

Runs a JavaScript script on a runner machine.

Example:

function main() {
return { message: "Hello, world!" };
}

The script can read payloads from previous nodes using the $ object.

Example:

function main() {
const commitSHA = $["On Git Push"].data.after;
const commitMessage = $["On Git Push"].data.message;
const imageTag = `example-image-${commitSHA}`;
return { imageTag: imageTag };
}

The script returns a JSON object that is passed to the next node on the canvas.

function main() {
return { message: "Hello, world!" };
}

Before executing the script, the runner can install node packages using the npm install command as part of the setup commands.

Setup commands:

Terminal window
npm install @octokit/rest

Script:

function main() {
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
});
const response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {
owner: 'octokit',
repo: 'octokit.js',
path: 'README.md',
});
return { contents: response.data };
}

Runs a Python script on a runner machine.

Example:

def main():
return { message: "Hello, world!" }

The script can read payloads from previous nodes using the $ object.

Example:

def main():
const commitSHA = $["On Git Push"].data.after;
const commitMessage = $["On Git Push"].data.message;
const imageTag = `example-image-${commitSHA}`;
return { imageTag: imageTag };
}

The script returns a JSON object that is passed to the next node on the canvas.

def main():
return { message: "Hello, world!" }

Before executing the script, the runner can install Python packages using the pip install command as part of the setup commands.

Setup commands:

Terminal window
pip install @octokit/rest

Script:

import octokit
def main():
octokit = octokit.Octokit({
auth: process.env.GITHUB_TOKEN,
})
response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {
owner: 'octokit',
repo: 'octokit.js',
path: 'README.md',
})
return { contents: response.data }

Every runner node requires a machine type that will run your script. Pick one that matches the architecture and size your workload needs.

Machine typeArchitecturevCPUsMemory
e1-large-amd64AMD64416GB
e1-large-arm64ARM64416GB
e1-tiny-amd64AMD640.51GB
e1-tiny-arm64ARM640.51GB

Every task runs in one of two execution modes:

Execution modeWhere work runs
HostDirectly on the runner machine (default)
DockerInside a container image you choose

Use Docker when you need an isolated environment or a specific toolchain image.

When using Docker mode, you can select a container image in the UI in two ways:

  • Preset: Choose from a dropdown of commonly used, pre-configured images (e.g., node:22-slim, python:3.12-slim).
  • Custom: Select “Custom image” and type the exact image reference (e.g., registry.example.com/my-tools:1.2.3).

You can pass environment variables to your runner scripts using the Environment Variables section in the node configuration. These variables are securely injected into the execution environment (both Host and Docker modes) and are available to your shell commands or scripts via standard environment variable syntax (e.g., $MY_VAR in Bash, process.env.MY_VAR in Node.js, os.environ.get('MY_VAR') in Python).

Pre-installed software on the host machine

Section titled “Pre-installed software on the host machine”

The runner machine comes with the following pre-installed software.

SoftwareVersion
Ubuntu24.04 LTS
Bash5.2
Docker CE29.5.3
Docker Buildx0.34.1
Docker Compose5.1.4
Node.js22.22
Python3.12.3
AWS CLI2.34

Use these directly in shell commands, Bash scripts, and setup commands.

Runners are Generally Available (GA) for production workloads.

A runner task progresses through the following states:

  1. Queued: The task is waiting for an available runner machine in the fleet.
  2. Claimed: A runner machine has picked up the task and is preparing the environment (e.g., pulling Docker images).
  3. Running: The script or commands are currently executing.
  4. Succeeded / Failed / Canceled: The terminal state of the task.

While a task is executing, you can view its live output directly from the Canvas. Click the View logs button on the running node to open a streaming log viewer. This helps you monitor long-running builds or scripts in real-time.

You can cancel a running task at any time. When you cancel a run from the Canvas UI or via the API, SuperPlane sends a cancellation signal to the task broker, which terminates the process on the runner machine and marks the task as Canceled.

Instance administrators can view all active runner tasks across the entire system. Navigate to the Admin Panel > Runner Tasks to see a live table of tasks that are currently queued or claimed. This view includes the task ID, status, fleet ID, runner ID, execution mode, and lifecycle timestamps.

If a task is not progressing as expected:

  • Stuck in Queued: Check if your runner fleet has available machines or if the machines are offline.
  • Fails immediately: Check the run history or live logs. Common issues include syntax errors in the script, missing environment variables, or an invalid custom Docker image reference.
  • Hangs in Running: Ensure your script does not contain infinite loops or wait for interactive input. You can configure an execution timeout on the node to automatically kill hanging tasks.

For more on how payloads flow between nodes, see Data Flow. For expression syntax inside runner scripts and node configuration, see Expressions.