Runefile (server config)

The schema for runed's server configuration file.

runed is configured via a YAML or TOML file (often called a "runefile"). The default location is /etc/rune/runefile.{yaml,toml}runed auto-discovers either format. Override with runed --config <path>.

The two formats are equivalent; pick whichever your tooling prefers. TOML is recommended for new deployments because it's stricter about typos and easier to comment.

Minimal example

server:
  grpc-addr: ":7863"
  http-addr: ":7861"
  data-dir: /var/lib/rune
 
auth:
  enabled: true

Full example

server:
  grpc-addr: ":7863"
  http-addr: ":7861"
  data-dir: /var/lib/rune
  log-level: info
  log-format: json
 
auth:
  enabled: true
  allow_remote_admin: false
  tls:
    enabled: true
    cert-file: /etc/rune/tls/server.crt
    key-file:  /etc/rune/tls/server.key
 
crypto:
  kek:
    source: file              # file | env | generated
    file-path: /var/lib/rune/kek
    env-var: RUNE_MASTER_KEY
    generate-if-missing: true
 
storage:
  secret-limits:
    max-keys-per-secret: 64
    max-value-size: 65536
 
runner:
  docker:
    enabled: true
    socket: /var/run/docker.sock
  process:
    enabled: true
 
docker:
    registries:
      - name: ghcr-private
        registry: ghcr.io
        auth:
          type: basic
          username: ${GHCR_USER}
          password: ${GHCR_PAT}
      - name: ecr
        registry: "*.dkr.ecr.us-east-1.amazonaws.com"
        auth:
          type: ecr
          region: us-east-1

Sections

server

FieldDefaultNotes
grpc-addr:7863gRPC listen address.
http-addr:7861REST gateway + web dashboard listen address.
data-dirOS-specificBadgerDB + state. Persist across restarts.
log-levelinfodebug, info, warn, error.
log-formattexttext or json.

auth

FieldDefaultNotes
enabledtrueSet to false only for local dev.
allow_remote_adminfalseIf true, admin/* works from non-localhost clients.
tls.enabledfalseRecommend true in production.
tls.cert-fileServer cert.
tls.key-fileServer key.

ui

The embedded web dashboard, served on server.http-addr.

FieldDefaultNotes
enabledtrueServe the dashboard at path.
path/uiMount point.
handoff_enabledtrueAllow the rune ui one-time-code browser sign-in.
handoff_ttl60sLifetime of a handoff code.
require_tlstrueWithout TLS, bind the HTTP listener to loopback only — no plaintext on a public address.

crypto.kek

How runed loads the Key Encryption Key for secrets.

FieldNotes
sourcefile, env, or generated.
file-pathUsed when source: file.
env-varUsed when source: env (e.g. RUNE_MASTER_KEY).
generate-if-missingIf true, create a new KEK and persist (mode 0600).

The KEK is 32 bytes, base64-encoded when stored on disk or passed via env.

storage.secret-limits

FieldDefaultNotes
max-keys-per-secret64Per-secret key count cap.
max-value-size65536Per-value size cap (bytes).

storage (volumes)

Controls the persistent-storage subsystem. See the storage concept and storage resources reference.

FieldDefaultNotes
defaultStorageClasslocalCluster default class. Empty string disables the default — claimTemplate without storageClassName becomes a cast-time error.
localVolumeRoot/var/lib/rune/volumesRoot for the local driver's managed directory tree.
hostPathAllowlist[]Allowed prefixes for local-host hostPath. Empty list denies all hostPath usage. runed --dev-mode overlays ["~/.rune/volumes"].
allowCreateMissingfalseWhen true, honour local-host parameters.createIfMissing: "true". runed --dev-mode overlays true.
preserveOnDeletefalse(local driver only.) When true, converts reclaimPolicy: delete to retain — directories survive cascade.
[storage]
defaultStorageClass = "local"
localVolumeRoot = "/var/lib/rune/volumes"
hostPathAllowlist = ["/mnt/rune", "/var/lib/rune-volumes"]
allowCreateMissing = false
 
[storage.local]
preserveOnDelete = false

storage.drivers

Per-driver configuration is keyed by registered driver name. Reserved for non-credential, non-per-class driver knobs only — credentials and per-class settings live on StorageClass.parameters so they can be rotated and varied per class. The do-volume driver currently takes no runefile knobs (its API token is sourced from StorageClass.parameters.apiToken, see Storage resources).

# Example placeholder — no driver currently requires any of these.
# [storage.drivers.<driver-name>]
# someKnob = "value"

runner

SectionFieldNotes
dockerenabledSet false to disable container support.
dockersocketDocker daemon socket. Default OS-specific.
processenabledSet false to disable process runner.

docker.registries[]

docker:
  registries:
    - name: ghcr-private
      registry: ghcr.io
      auth:
        type: basic
        username: ${GHCR_USER}     # env-expanded at runed start
        password: ${GHCR_PAT}
 
    - name: ecr
      registry: "*.dkr.ecr.us-east-1.amazonaws.com"
      auth:
        type: ecr
        region: us-east-1
        # AWS credentials inferred from environment / IAM role.
Auth typeRequired fieldsNotes
basicusername, passwordUse for GHCR (PAT as password), Docker Hub, etc.
tokentokenBearer token in the Authorization header.
ecrregionPulls a fresh ECR token via the AWS SDK.
dockerconfigjsondockerconfigjson (raw JSON)Reuse the contents of ~/.docker/config.json.

Credentials from a Rune Secret (fromSecret)

Instead of inlining credentials, an entry can resolve them from an encrypted Rune Secret at runtime — the recommended pattern for production:

docker:
  registries:
    - name: ghcr-private
      registry: ghcr.io
      auth:
        fromSecret: ghcr-credentials   # Secret name; runed infers auth type from its keys

runed infers the auth type from the secret's keys: username+passwordbasic, token → bearer, .dockerconfigjson → docker config JSON, awsAccessKeyId+awsSecretAccessKey (+ optional awsRegion) → ecr. When fromSecret is set, do not also set type or inline username/password/token — they are ignored.

For first-boot bootstrapping (e.g. from the Terraform module), the entry can also seed the secret on startup:

FieldNotes
fromSecretName of the Rune Secret to read credentials from at pull time.
bootstrapIf true, runed creates/updates the secret from data on first start (manage controls re-apply).
managecreate (default) or update. update overwrites the secret on every start; create is one-shot.
immutableIf true, the seeded secret rejects subsequent writes via the API.
dataBootstrap seed map (env-expanded against runed's process env). Ignored at runtime resolution — only consumed when bootstrap = true.

Manage credentials at runtime with rune admin registry — no restart required. See the GHCR guide for a private-image walkthrough.

networking

The cluster networking layer. See Concepts: Networking for what these knobs do.

FieldDefaultNotes
cluster_cidr10.96.0.0/16Service VIP pool. Set once at first start — bootstrapped into the store.
dev_modefalseUse a userland proxy instead of nftables. Required on macOS / Docker Desktop. Implies node.role: edge unless you explicitly set a different role.

telemetry

FieldDefaultNotes
metrics_addr127.0.0.1:9100Prometheus /metrics endpoint. Exposes metrics from all subsystems (orchestrator, runners, networking, agent, DNS). Set to "" to disable.

node

FieldDefaultNotes
roleworkerworker or edge. edge enables the ingress + ACME subsystems.

ingress

Only consulted on edge nodes (node.role: edge).

FieldDefaultNotes
http_addr:80HTTP listener (also serves ACME challenges).
https_addr:443HTTPS listener.

acme

Only consulted on edge nodes.

FieldDefaultNotes
directoryhttps://acme-v02.api.letsencrypt.org/directoryACME endpoint. Override for staging or Pebble in CI.
emailAccount contact. Required by Let's Encrypt — issuance fails without it.

Issued certificates are persisted in the encrypted state store (one Secret per host under the system namespace), so runed restarts reuse them rather than re-issuing — important because Let's Encrypt rate-limits to 5 issuances per identifier set per 168 h.

TOML equivalent

data_dir = "/var/lib/rune"
 
[server]
grpc_address = ":7863"
http_address = ":7861"
 
[networking]
cluster_cidr = "10.96.0.0/16"
 
[telemetry]
metrics_addr = "127.0.0.1:9100"
 
[node]
role = "edge"
 
[ingress]
http_addr  = ":80"
https_addr = ":443"
 
[acme]
email = "[email protected]"

CLI flag overrides

Anything in the runefile can be overridden via runed flags:

FlagOverrides
--configpath to this file
--data-dirserver.data-dir
--grpc-addrserver.grpc-addr
--http-addrserver.http-addr
--log-levelserver.log-level
--log-formatserver.log-format
--debugshorthand for --log-level=debug
--prettyshorthand for --log-format=text
--cluster-cidrnetworking.cluster_cidr
--dev-modenetworking.dev_mode
--metrics-addrtelemetry.metrics_addr
--node-rolenode.role
--ingress-http-addringress.http_addr
--ingress-https-addringress.https_addr
--acme-directoryacme.directory
--acme-emailacme.email

Every key also has a corresponding RUNE_* environment variable (e.g. RUNE_NETWORKING_CLUSTER_CIDR, RUNE_TELEMETRY_METRICS_ADDR, RUNE_ACME_EMAIL). Precedence, highest to lowest: flag > env var > config file > built-in default.

Reload behavior

Most fields require a runed restart to take effect. Registry credentials managed via rune admin registry are hot.

See also