Run Opergow host tasks on your own infrastructure: Docker, Kubernetes or Linux. Scale with one key.
119
The Opergow Runner executes the host tasks of your Opergow workflows on your own infrastructure — as a Docker container, in Kubernetes or on a Linux server. It signs in with a runner key of your organisation, picks up the tasks of the key's runner pool, runs them locally and returns the results.
| Tag | Base | Contents |
|---|---|---|
1.0.0 | Debian slim with apt | runner + bash, curl, git, jq, python3 |
1.0.0-minimal | distroless (static) | runner only — built-in actions and API calls |
Both tags are available for linux/amd64 and linux/arm64. Pin an exact version; there is no latest tag.
In the Opergow web app, open Runner, create a pool and save the key (ork_eu_…, shown only once) to a file
named runner_key with mode 0600.
Check the key and the connection:
docker run --rm --user "$(id -u):$(id -g)" \
-v "$PWD/runner_key:/run/secrets/opergow/runner_key:ro" \
docker.io/opergow/runner:1.0.0 check
Start the runner:
docker run -d --name opergow-runner --restart unless-stopped \
--user "$(id -u):$(id -g)" -e HOME=/tmp \
--read-only --tmpfs /work:mode=1777 --tmpfs /tmp:mode=1777 \
--cap-drop ALL --security-opt no-new-privileges --stop-timeout 90 \
-v "$PWD/runner_key:/run/secrets/opergow/runner_key:ro" \
-e OPERGOW_RUNNER_LABELS=docker,linux \
docker.io/opergow/runner:1.0.0
--user runs the container as the owner of runner_key, so the key file can keep mode 0600.
The instance appears under Runner → Instances. In the Studio, select the runner pool as the target of a host task.
services:
runner:
image: docker.io/opergow/runner:1.0.0
restart: unless-stopped
user: "${RUNNER_UID:-65532}:${RUNNER_GID:-65532}"
environment:
OPERGOW_RUNNER_LABELS: "docker,linux"
HOME: /tmp
secrets:
- source: opergow_runner_key
target: /run/secrets/opergow/runner_key
stop_grace_period: 90s
read_only: true
tmpfs:
- /work:mode=1777
- /tmp:mode=1777
cap_drop: [ALL]
security_opt: ["no-new-privileges:true"]
secrets:
opergow_runner_key:
file: ./runner_key
Start with RUNNER_UID=$(id -u) RUNNER_GID=$(id -g) docker compose up -d; scale with
docker compose up -d --scale runner=3.
kubectl create secret generic opergow-runner-key --from-file=runner_key=./runner_key
apiVersion: apps/v1
kind: Deployment
metadata:
name: opergow-runner
spec:
replicas: 2
selector:
matchLabels: { app: opergow-runner }
template:
metadata:
labels: { app: opergow-runner }
spec:
automountServiceAccountToken: false
terminationGracePeriodSeconds: 90
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile: { type: RuntimeDefault }
containers:
- name: runner
image: docker.io/opergow/runner:1.0.0
env:
- name: OPERGOW_RUNNER_INSTANCE
valueFrom: { fieldRef: { fieldPath: metadata.name } }
- name: OPERGOW_RUNNER_LABELS
value: "k8s,linux"
- name: HOME
value: /tmp
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities: { drop: ["ALL"] }
ports:
- { name: health, containerPort: 8080 }
livenessProbe: { httpGet: { path: /healthz, port: health }, periodSeconds: 20 }
readinessProbe: { httpGet: { path: /readyz, port: health }, periodSeconds: 10 }
volumeMounts:
- { name: runner-key, mountPath: /run/secrets/opergow/runner_key, subPath: runner_key, readOnly: true }
- { name: work, mountPath: /work }
- { name: tmp, mountPath: /tmp }
volumes:
- name: runner-key
secret:
secretName: opergow-runner-key
defaultMode: 0440 # octal (288 in JSON): readable for the pod's group 65532
items: [{ key: runner_key, path: runner_key }]
- { name: work, emptyDir: {} }
- { name: tmp, emptyDir: {} }
Every pod is one instance of the pool; scale with kubectl scale deployment opergow-runner --replicas=5.
Only a key file and environment variables — everything else comes from the pool profile.
| Setting | Default | Meaning |
|---|---|---|
/run/secrets/opergow/runner_key | — | The runner key (file). Other path: OPERGOW_RUNNER_KEY_FILE. |
OPERGOW_RUNNER_INSTANCE | host name | Instance ID, unique per running container. |
OPERGOW_RUNNER_LABELS | — | Comma-separated labels (name or name=value, max. 16). Tasks that require labels run only on instances that carry all of them. |
OPERGOW_RUNNER_HEALTH_ADDR | :8080 | Address of /healthz, /readyz and /metrics. |
OPERGOW_RUNNER_LOG_LEVEL | pool profile | debug, info, warn or error. |
OPERGOW_RUNNER_WORKDIR | /work | Base of the per-task work directories (deleted after each task). |
OPERGOW_RUNNER_CREDENTIALS_DIR | /run/secrets/opergow/credentials | Tool credentials, one JSON file or folder per credential; the values never leave your machine. |
OPERGOW_RUNNER_WAKE | on | off disables the wake-up connection (polling only). |
Build on the standard image:
FROM docker.io/opergow/runner:1.0.0
USER root
RUN apt-get update \
&& apt-get install -y --no-install-recommends ffmpeg \
&& rm -rf /var/lib/apt/lists/*
USER runner
The Opergow web app can also generate this Dockerfile for you (Runner → Images) or, depending on your plan, build the image in the cloud and host it for you.
/healthz, /readyz and /metrics (Prometheus format) on port 8080. Logs are JSON lines on stdout; they never
contain the key, tokens or credential values.
Apache License 2.0.
Content type
Image
Digest
sha256:558280080…
Size
4.2 MB
Last updated
4 days ago
docker pull opergow/runner:1.0.0-minimal