Deployment templates
Example configuration files and systemd units for running the orchestrator and agent as services. Copy a template, then change the values your deployment requires. See the Getting Started guide for the full walkthrough.
agent.yaml.example
# Ordo agent configuration — example.## Every option is shown with its default value, all commented out: the defaults# are sensible, so an agent runs with no configuration at all. Uncomment only# what you want to change. The agent hot-reloads this file when started with# `--config`, so changes apply without a restart.## The orchestrator address is NOT set here — it is passed to the `connect`# subcommand (e.g. `ordo-agent connect 192.168.40.243:4747`).## Schema (editor autocompletion / CI validation):# https://getordo.dev/schemas/agent-config/v1.json
# ── Remote terminal (defaults shown) ────────────────────────────────────────# Lets operators open interactive PTY sessions on this machine through the# orchestrator. Disabled by default.# remote_terminal:# enabled: false# shell: "" # empty = platform default (/bin/bash, powershell.exe)# allow_operator_shell_override: false # let the operator choose the shell per session# max_sessions: 100 # max concurrent terminal sessions
# ── Metrics (defaults shown) ────────────────────────────────────────────────# System health reporting (disk, memory, CPU) to the orchestrator.# metrics:# enabled: true# collection_interval: 30 # seconds between samplesorchestrator.yaml.example
# Ordo orchestrator configuration — example.## Every option is shown with its default value. Commented lines are defaults you# can leave alone; uncomment and change only what you need. The uncommented# settings below are the ones a real deployment must or should set.## Schema (editor autocompletion / CI validation):# https://getordo.dev/schemas/orchestrator-config/v1.json
# ── Must be set on first run ────────────────────────────────────────────────# The bootstrap operator. Both are required the first time the orchestrator# starts (when no operators exist yet) and ignored on every start afterwards.# Get the public key from `ordo operator init` (or `ordo operator whoami`).bootstrap_key: "PASTE_OPERATOR_PUBLIC_KEY_HEX"# 1-64 letters/digits/-/_, must start with a letter.bootstrap_username: "CHOOSE_A_USERNAME"
# ── Recommended ─────────────────────────────────────────────────────────────# Interface the management API binds. The default (127.0.0.1) is reachable only# from the orchestrator host itself — fine for a single-machine/dev setup. Bind# all interfaces so the web UI and CLI work from other machines; choose a# specific address for a more complex network.api_host: "0.0.0.0"
# ── Networking (defaults shown) ─────────────────────────────────────────────# TCP port on which the orchestrator accepts agent connections.# agent_port: 4747# HTTP port on which the management API is served.# api_port: 4748# Address advertised to agents during discovery; empty = auto-detect.# advertised_host: ""
# ── TLS (defaults shown) ────────────────────────────────────────────────────# TLS is enabled by default; a self-signed certificate is generated on first# start and pinned by clients on first connection (trust-on-first-use).# tls_enabled: true# Provide both to use your own PEM certificate instead of the self-signed one.# tls_cert: "/etc/ordo/tls/cert.pem"# tls_key: "/etc/ordo/tls/key.pem"# Assert that a TLS-terminating reverse proxy fronts the API. Only relevant when# tls_enabled is false; permits secret writes over the (proxied) plaintext hop.# trust_proxy_tls: false
# ── Capacity and sessions (defaults shown) ──────────────────────────────────# Maximum number of simultaneously pending agents awaiting approval.# pending_capacity: 100# Seconds a web UI / API session token remains valid.# session_token_expiry_secs: 3600
# ── Metrics (defaults shown) ────────────────────────────────────────────────# metrics:# poll_interval: 60 # seconds between polling each agent for metrics# retention: 86400 # seconds to retain metric samples (24h)
# ── Audit log (defaults shown) ──────────────────────────────────────────────# audit:# retention_days: 90 # 0 disables automatic pruning
# ── Drift detection (defaults shown) ────────────────────────────────────────# drift:# enabled: true# interval: 3600 # seconds between drift checks per agent# max_concurrent: 8 # max in-flight drift checks across all agents# skip_recently_applied: 300 # suppress checks for N seconds after an apply# retention_days: 30 # how long to retain drift recordsordo-agent.service
[Unit]Description=Ordo agentDocumentation=https://docs.getordo.devAfter=network-online.targetWants=network-online.target
[Service]Type=simple# Top-level options (--config, --data-dir) come BEFORE the `connect` subcommand;# replace the address with your orchestrator's host:agent_port.ExecStart=/usr/local/bin/ordo-agent --config /etc/ordo/agent.yaml --data-dir /var/lib/ordo-agent connect ORCHESTRATOR_HOST:4747Restart=on-failureRestartSec=5
# The agent manages this machine — it writes files and controls services as# declared state requires — so it runs as root WITHOUT the filesystem sandboxing# used for the orchestrator. ProtectSystem/ProtectHome/DynamicUser would stop it# doing its job. StateDirectory persists the agent's identity and pinned# orchestrator key.User=rootStateDirectory=ordo-agent
[Install]WantedBy=multi-user.targetordo-orchestrator.service
[Unit]Description=Ordo orchestratorDocumentation=https://docs.getordo.devAfter=network-online.targetWants=network-online.target
[Service]Type=simpleExecStart=/usr/local/bin/ordo-orchestrator --config /etc/ordo/orchestrator.yaml --data-dir /var/lib/ordo-orchestratorRestart=on-failureRestartSec=5
# Isolated transient system user; StateDirectory gives a persistent, owned# /var/lib/ordo-orchestrator for the identity key and the redb store. The# orchestrator only talks over the network and reads its config, so it can run# fully sandboxed (unlike the agent, which manages the host).DynamicUser=yesStateDirectory=ordo-orchestratorStateDirectoryMode=0750
# HardeningNoNewPrivileges=yesProtectSystem=strictProtectHome=yesPrivateTmp=yesPrivateDevices=yesProtectKernelTunables=yesProtectKernelModules=yesProtectControlGroups=yesRestrictAddressFamilies=AF_INET AF_INET6RestrictNamespaces=yesLockPersonality=yesSystemCallFilter=@system-serviceSystemCallErrorNumber=EPERM
[Install]WantedBy=multi-user.target