Repository navigation
RunR 0.6.7
RunR is an open-source, self-hosted serverless platform on Kubernetes and Knative: functions, containers, sandboxes, WebAssembly and durable workflows, with an API, a web console, the runr CLI, SDKs, a Terraform provider and a GitHub Action. You install it on infrastructure you operate, connected or air-gapped. It is developed by BRF Teknoloji and released under the MIT License.
0.6.7 is a maintenance release of 0.6.6. It fixes sandbox commands on Kata Containers 4.3.1 and gVisor, whose runtimes lost a command's input or output while the command still exited 0: on Cloud Hypervisor, QEMU and Firecracker a command's output stopped once its input ended, on Dragonball input over 64 KiB ended at 64 KiB, and on gVisor a write over 64 KiB could lose its end. Input that arrives short now fails with a message on every class. kube-prometheus-stack 92.21.2 (Prometheus v3.16.0) comes to new regions, and to existing ones by a command of the operator, and a sandbox command starts one process less.
Nothing needs a step: there is no database migration, Kata is not reinstalled, and running sandboxes keep running. Two things to know: a command on gVisor takes about 100 ms more, and a custom sandbox image needs cat and mkfifo.
Install
- Kubernetes (Helm): the chart comes from BRF's public Helm repository, without credentials:
See the README and docs/install.md;
helm repo add brf-tech https://helm.brf.sh helm upgrade --install runr brf-tech/runr --namespace runr --create-namespace --set domain=runr.example.com
helm show values brf-tech/runrlists every value. A pinned install adds--version 0.6.7; the API and UI images, the region agent and the event gateway follow the chart version. - Single host (Docker Compose, also air-gapped): compose/README.md, from a checkout of the release tag (
git clone -b v0.6.7 https://github.com/BRF-Tech/runr.git). - CLI:
curl -fsSL https://runr.sh/install.sh | shon Linux and macOS. The archives of every platform are at runr.sh/dl (https://runr.sh/dl/cli/v0.6.7/) and attached below; check them againstchecksums.txt(docs/cli.md#install). - Terraform / OpenTofu:
source = "brf-tech/runr",version = "~> 0.6", from the Terraform Registry;terraform initchecks the archive againstSHA256SUMS, signed with the RunR release key (key ID2588846B241BC095). runr.sh serves the same archives underrunr.sh/brf-tech/runr, for OpenTofu and for configurations that use that address (docs/terraform.md#install). - GitHub Action:
uses: brf-tech/runr/actions/deploy@v0.6.7; it downloads the CLI from runr.sh (docs/github-action.md). - Images: every image is published under
ghcr.io/brf-tech/runrby release-images.yml, for linux/amd64 and linux/arm64, and pulls anonymously.
The documentation is at runr.sh/docs and in the documentation index here.
Upgrading from 0.6.6
Upgrade in place with helm upgrade of the running release; never uninstall and install again, and back up the database first (Procedure in docs/upgrade.md). From 0.6.6 there is no database migration, the images keep their names, and nothing has to be set (0.6.6 → 0.6.7).
helm repo update brf-tech
helm upgrade runr brf-tech/runr --version 0.6.7 -n runr --reuse-values- Sandbox commands on Kata and gVisor travel differently. On Kata's Go runtime (Cloud Hypervisor, QEMU, Firecracker) a command's stdin is no longer closed while it runs: an
/execwithstdintakes one exec more, as the input is written into the sandbox first and the command reads it from there. On Dragonball, input goes in acknowledged frames of 48 KiB, the next once the sandbox read the last: a 10 MiB upload took 6.6 s on the single-node test VM. On gVisor, a user command writes through pipes inside the sandbox, which costs about 100 ms per command on that VM; terminal sessions are unchanged. Running sandboxes, those started by 0.6.6 included, run their next command the new way (Sandbox input and output). - Input that arrives short fails. On every class, an upload, an archive, the
stdinof/execand the code of a code run are checked once written: one that arrived short fails withrunr: the input ended after N of M bytes(the upload,the archivefor those) instead of being stored short. An archive is written to/tmp/.runr/execand checked before it is extracted, so while it is extracted it takes its size on the sandbox's disk twice. - A custom sandbox image (
sandbox.allow_custom_images) now needscatfor/execwithstdin,mkfifofor the exec WebSocket without a terminal, and on Dragonballheadorddfor any input. coreutils and busybox have them all. - The region agent and the event gateway move to 0.6.7. As in 0.6.0 to 0.6.6, they run at the installed version: after
helm upgradereturned, the Jobrunr-region-reconcile-<revision>moves the regions' agents, queue consumers and topic publishers fromagent:0.6.6/queue-consumer:0.6.6toghcr.io/brf-tech/runr/agent:0.6.7andqueue-consumer:0.6.7; each rolls once. A region that pulls through a mirror of your own needs these two images there before the upgrade (Order of operations). - kube-prometheus-stack does not move by itself, because the move restarts Prometheus.
php artisan cluster:patch-observabilitymoves a region to 92.21.2 when it suits the region: Prometheus and its operator restart once, and no CRD step is needed. A region whose nodes pull through a mirror of their own needsquay.io/prometheus/prometheus:v3.16.0-distrolessandghcr.io/jkroepke/kube-webhook-certgen:1.11.1there first (kube-prometheus-stack 92.21.2). - While the API and reverb pods roll, an exec WebSocket without a terminal that reaches a reverb pod of 0.6.6 runs as it did in 0.6.6.
- Back to 0.6.6: a plain
helm rollback(orhelm upgradewith the 0.6.6 chart where only one package version is kept) on the same database; there is no migration to undo. The region Job of the 0.6.6 chart moves the region images back to 0.6.6, and Kata is not reinstalled either way. Sandbox commands then run the 0.6.6 way again, with the runtime bugs above. A region moved to kube-prometheus-stack 92.21.2 keeps it. - Terraform provider 0.6.7: its resources and data sources are the ones of 0.6.6.
From 0.6.5, upgrade straight to 0.6.7 and read 0.6.5 → 0.6.6 as well: 0.6.6 re-runs kata-deploy with Kata Containers 4.3.1, which stops the running Kata pods of every region with Kata, the region Traefik moves to chart 42.3.0 and deletes request headers with _ or . in their names, and Reverb refuses client events. From 0.6.4, also read 0.6.4 → 0.6.5: 0.6.5 adds the notification_user_states migration, the Helm value notifications.retentionDays, and its daily task deletes notifications older than 90 days. From 0.6.3, also read 0.6.3 → 0.6.4: 0.6.4 adds the captcha_settings migration and the Helm values captcha.*, and its first upgrade rolls the pods once. From 0.6.2, also read 0.6.2 → 0.6.3; from 0.6.1, also 0.6.1 → 0.6.2. From 0.6.0, also read 0.6.0 → 0.6.1 first: before a rollback to 0.6.0, let the running deploys finish (Rolling back to 0.6.0). From 0.5.10, read 0.5.10 → 0.6.0 in docs/upgrade.md first — in particular what to decide before the upgrade — and the notes of 0.6.0 to 0.6.6 in CHANGELOG.md; everything said there applies. From 0.5.9 or earlier, read the notes of the releases in between as well; from 0.5.8 or earlier, add --set api.image.tag= --set ui.image.tag= to that upgrade once (step 3 of the Procedure).
Changes in 0.6.7 (2026-11-06)
Upgrade notes
- Nothing needs a step. There is no database migration, Kata is not reinstalled, and running
sandboxes keep running: their next command runs the new way. See
docs/upgrade.md. - A sandbox command on gVisor takes about 100 ms more on the single-node test VM: it
writes through pipes inside the sandbox, so that a large write no longer loses its end. On
Dragonball, input goes in acknowledged frames of 48 KiB (a 10 MiB upload took 6.6 s on the same
VM). See docs/upgrade.md. - A custom sandbox image (
sandbox.allow_custom_images) now needscatfor/execwith
stdin,mkfifofor the exec WebSocket without a terminal, and on Dragonballheadorddfor
any input. coreutils and busybox have them all. - kube-prometheus-stack 92.21.2 does not reach an installed region by itself:
php artisan cluster:patch-observabilitymoves it and restarts Prometheus once. See
docs/upgrade.md.
Changed
- A sandbox command starts one process less. Every command ran
mkdir -p /tmp/.runr/exec
before it wrote its PID file; the sandbox pod now creates that directory (and
/tmp/.runr/code) when it starts, and a command writes its PID file with the shell alone. On
the single-node test VM (nested KVM, Kata 4.3.1) a command took 22–37 ms less at the median on
Cloud Hypervisor, QEMU, Dragonball and gVisor (kubectl exec of the command's wrapper, n=60 per
class; Firecracker unchanged). The code interpreter and the files of a create or of a claimed
warm pod start no mkdir when their directories exist. Sandboxes started by 0.6.6 or earlier
create the directory on their first command. - kube-prometheus-stack 92.21.2 (Prometheus v3.16.0, kube-webhook-certgen 1.11.1; the Prometheus
Operator stays at v0.94.2). Regions installed from now on run it; an installed region keeps its
chart untilphp artisan cluster:patch-observability, a change back to RunR's own monitoring or a
new Serving install moves it. The move restarts Prometheus and its operator once and needs no step
of its own: the operator's CRDs are the same. The chart no longer puts its version in the labels of
the operator's pod, so a later chart upgrade restarts the operator only when the operator changes
(upgrade.md).
Fixed
- On Kata, a sandbox command's output no longer stops when its input ends. With Kata
Containers 4.3.1 (RunR 0.6.6), the Go runtime behind Cloud Hypervisor, QEMU and Firecracker
stops passing a command's stdout once the exec's stdin is closed:/runwith more than 32 KiB
of output timed out with 32 KiB,/execwithstdinlost what the command wrote after its
input ended (and more than 32 KiB of it hung until the timeout), and the exec WebSocket lost the
output afterstdin_close. RunR no longer closes an exec's stdin while a command runs: the
input of/execand the code of/runare written into the sandbox by an exec of their own and
read from there (an input whose command never started is removed after an hour), uploads and the
env file of a claimed warm pod take exactly their bytes, and the exec WebSocket passes its input
on in frames that end in-band, with the exit code from a marker the command's wrapper writes; a
kill reaches the command through its PID file as before. Dragonball (runtime-rs) and gVisor were
not affected. A custom image now needscatfor/execwithstdinandmkfifofor the exec
WebSocket without a terminal (upgrade.md). - On Dragonball, input over 64 KiB no longer ends at 64 KiB. Kata 4.3.1's Rust runtime with the
Dragonball VMM ends an exec's stdin once 64 KiB of it wait unread in the guest, and the command
still exits 0: an upload over 64 KiB was stored short (100000 bytes written, 65536 read back), and
/execwithstdin, a code run's code and the files of a create over 64 KiB were cut. Input to a
Dragonball sandbox now goes in acknowledged frames of 48 KiB, the next once the sandbox read the
last (on the single-node test VM a 10 MiB upload took 6.6 s). On every class, input that arrives
short now fails with a message instead of being stored, and an archive is checked before it is
extracted: tar takes an archive cut between two files without a word. - On gVisor, a large write of a command no longer loses its end. gVisor returns a short write
when a program writes more than 64 KiB at once to an exec's stdout or stderr, and programs that do
not write the rest lose it: Python'sprint("y" * 100000)came back with 65537 bytes (RunR's Python
runtime runs unbuffered). A user command on gVisor now writes through pipes inside the sandbox,
whosecatwrites everything, with its exit code, kill and timeout as before; this costs about
100 ms per command on the single-node test VM. Kata and runc were not affected. - kubectl's "command terminated with exit code N" no longer ends a command's stderr when that
stderr did not end in a newline and the trailer came in the same piece of output.