Skip to content

RunPod Setup

This guide walks you through running a Reoclo Lite Runner inside a RunPod pod. You’ll get CPU/RAM/disk stats, GPU model detection, and remote shell access from your Reoclo dashboard — without installing Docker inside the pod.

If you’re new to Lite mode, start with Lite Runner overview — this guide assumes you already understand the Lite vs Full split.

  • A Reoclo tenant with at least one user who can manage servers
  • A RunPod account
  • An OCI image registry the RunPod template can pull from (Docker Hub, GHCR, ECR, etc.)

The Reoclo Runner repository ships a reference Dockerfile for pod environments. It bakes the reoclo-runner binary into a minimal Ubuntu 22.04 base and ships a foreground entrypoint that reads config from env vars.

Terminal window
git clone https://github.com/reoclo/runner.git
cd runner/pod-image
# Build for amd64 (most RunPod GPU pods are x86_64)
docker build --build-arg RUNNER_VERSION=latest -t your-registry/reoclo-runner-pod:latest .
# Push
docker push your-registry/reoclo-runner-pod:latest

For reproducible pod templates, pin to a specific runner version:

Terminal window
docker build --build-arg RUNNER_VERSION=1.5.0 -t your-registry/reoclo-runner-pod:1.5.0 .

For pods that will restart over time, mint a reusable, hostname-scoped registration token bound to a specific Server record. Each pod restart reuses the token without rotating it, and a leaked token is limited to the single hostname it was issued for.

First, register a placeholder Server in the dashboard (or via API) with the hostname you’ll use for the pod — recommended pattern is runpod-<pod-id>. Then issue the token:

Terminal window
curl -X POST https://app.reoclo.com/api/admin/runners/tokens \
-H "Authorization: Bearer $REOCLO_AUTH" \
-H "Content-Type: application/json" \
-d '{
"label": "runpod-pod-template",
"server_id": "<server-uuid>"
}'

Response:

{
"plaintext_token": "rt_…",
"token": {
"allowed_hostnames": ["runpod-abc123"],
"for_server_id": "<server-uuid>",
"usage_count": 0
}
}

Save plaintext_token — you can’t retrieve it again.

In the RunPod console → TemplatesNew Template:

FieldValue
Container Imageyour-registry/reoclo-runner-pod:latest
Container Start Command(leave empty — uses the image’s entrypoint)
Environment VariablesSee below

Add these env vars:

NameValueNotes
REOCLO_TOKENrt_… from Step 2Mark as secret
REOCLO_GATEWAY_URLwss://api.reoclo.com/ws/runnerOr your self-hosted gateway
REOCLO_PROFILElite(optional — default is already lite)

You don’t need REOCLO_HOSTNAME — the entrypoint auto-derives it from $RUNPOD_POD_ID so each pod registers under a stable, unique hostname.

Spin up a pod from the template. Within ~30s you should see in your Reoclo FleetView:

  • A new Server entry with hostname runpod-<pod-id>
  • An amber Lite badge
  • Any GPUs detected by nvidia-smi (e.g. “1× RTX 4090”) as a violet GPU badge
  • Live CPU/RAM/disk stats
  • Working interactive shell via the dashboard

When RunPod recycles the pod (e.g. on a hardware migration), the pod restarts with the same $RUNPOD_POD_ID. The runner re-registers under the same hostname, the gateway treats it as an instance restart:

  • Same Server record is reused (same UUID)
  • restart_count is incremented
  • current_runner_session is replaced with the new connection’s metadata
  • Stale container_snapshots from the previous boot are purged
  • Metrics history, configured applications, and audit log are preserved

This means you can see “this pod has restarted N times” in the dashboard without losing observability data.

You can run Lite pods alongside Full Docker-based runners in the same tenant. Reoclo’s deploy dispatch refuses to send Docker applications to Lite servers — you’ll see a clear error at deploy time, not a silent failure later.

A common pattern is one Full runner on a control-plane VM (Hetzner, AWS, etc.) for application deploys, plus a fleet of Lite pods on RunPod for GPU workloads where you want shell access but not Reoclo-managed deploys.

Check the runner’s stdout in the RunPod logs. The most common cause is a token-scope rejection (the pod’s hostname doesn’t match allowed_hostnames). Verify the token was issued with the right server_id and that $RUNPOD_POD_ID matches your Server’s hostname.

You’re probably using a one-shot token (no for_server_id). Re-issue with server_id set so the token stays reusable.

Pod crash-loops on a minimal CUDA image (wget not found)

Section titled “Pod crash-loops on a minimal CUDA image (wget not found)”

Bare NVIDIA CUDA base images (e.g. nvcr.io/nvidia/cuda:*-base) ship without curl, wget, or python3. If the persistent runner start command is spliced into a pod built on one of these images, the pod may crash-loop with output like:

bash: line 7: wget: command not found
bash: line 12: /opt/reoclo/run.sh: No such file or directory

The start command now resolves this automatically by trying curl → wget → python3 and, if none are found, installing curl via the system package manager (apt-get, apk, dnf, or yum). To get the updated start command, re-apply the persistent runner from the dashboard Reinstall section for the affected pod. Alternatively, pre-install curl or wget in your pod image.

The pod image needs nvidia-smi available at runtime. RunPod’s CUDA base images include it by default; if you’re building from ubuntu:22.04 and need GPU detection, install the NVIDIA container toolkit drivers or extend the base image.

Lite runners support shell on Linux pods just like Full runners do. If the dashboard shell hangs, check that the pod is on a hardware-passthrough host (some RunPod tiers restrict pty allocation). Try a bash -i shell first via the dashboard’s “Custom Command” option.