Skip to content

Running runed

runed is one process. Run it under a supervisor, give it a stable data directory, and watch its logs. That’s the whole job.

The official server install drops a unit at /etc/systemd/system/runed.service. If you installed manually, here’s a known-good unit:

[Unit]
Description=Rune control plane
After=network-online.target docker.service
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/runed --config /etc/rune/runefile.yaml
Restart=on-failure
RestartSec=2s
LimitNOFILE=65536
StateDirectory=rune
User=root
# Or run as an unprivileged user with access to /var/lib/rune and the docker socket.
[Install]
WantedBy=multi-user.target

Lifecycle:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now runed
sudo systemctl status runed
sudo systemctl restart runed
sudo journalctl -u runed -f

--data-dir (default /var/lib/rune) holds:

  • BadgerDB state (services, instances, secrets ciphertexts, tokens, policies).
  • The KEK file, if crypto.kek.source: file.
  • Per-resource version history.

Back this up. Loss = loss of every service spec, secret, user, and policy.

Terminal window
# Snapshot
sudo systemctl stop runed
sudo tar -czf rune-backup-$(date +%F).tgz -C /var/lib rune
sudo systemctl start runed

For online backup, use BadgerDB’s snapshot tooling or copy while accepting that some recent writes may be missed. Multi-node with Raft snapshots is roadmap (RUNE-029).

runed writes logs to stdout. Under systemd, that goes to journald:

Terminal window
journalctl -u runed -f
journalctl -u runed --since "1 hour ago"
journalctl -u runed -p err # errors only

Configure verbosity in the runefile (server.log-level) or with --log-level. Use --log-format=json if you ship logs to a structured collector.

SignalBehavior
SIGTERMGraceful shutdown — drains gRPC, stops orchestrator, exits.
SIGINTSame as SIGTERM.
SIGHUPReserved (no-op today).

Graceful shutdown waits for in-flight RPCs (with a timeout) and writes any pending state. Don’t SIGKILL unless something is wedged — you risk losing recent writes.

server:
grpc-addr: ":7863" # bind all interfaces
http-addr: ":7861"

In production, bind to a private interface and front-door with TLS. To restrict to localhost:

server:
grpc-addr: "127.0.0.1:7863"
http-addr: "127.0.0.1:7861"

For Release 1 (single node):

Workload sizeRAMDiskCPU
≤ 20 services256 MiB1 GiB0.25 c
≤ 100 services512 MiB5 GiB0.5 c
≤ 500 services1 GiB20 GiB1 c

These are rough. Disk grows with secret/configmap version history — set storage retention to taste.

runed exposes a health endpoint at :7861/healthz. Use it for liveness from your host’s monitoring.

Terminal window
curl -fsS http://localhost:7861/healthz

Returns 200 when the orchestrator is reconciling. Returns 503 if the store is unreachable or shutting down.

ScenarioRecovery
runed crashesSystemd restarts it. State persists on disk.
Disk fillsReconciler logs errors; new writes fail. Free disk.
Docker daemon downContainer ops fail. Process services keep running.
KEK file deleted/corruptServer refuses to start. Restore from backup.
Bootstrap token lostRecover via local-only rune admin bootstrap (only works on a server with no live tokens — otherwise: restore from backup).