Getting Started
This guide walks you from nothing to a managed fleet, moving across three machines: your workstation, the orchestrator host, and a machine you want to manage. The configuration files and systemd units shown below are the same templates published with each release (also listed on the Deployment templates reference page).
What you will learn
Section titled “What you will learn”- Installing the right Ordo binaries on each machine
- Creating the first operator identity and bootstrapping an orchestrator
- Running the orchestrator and an agent as systemd services
- Approving and tagging an agent from the operator CLI
- Opening the web UI
Prerequisites
Section titled “Prerequisites”- A machine to run the orchestrator, and one or more machines to run agents. These can be the same machine while you are exploring — with one caveat: Ordo does not support an agent managing the orchestrator’s own host. Other state on that machine can still be managed normally.
- Network connectivity from each agent to the orchestrator on the agent port
(
4747by default).
1. Set up your workstation
Section titled “1. Set up your workstation”On the machine you will operate Ordo from, install the client tools (ordo and
ordo-state):
curl -fsSL https://getordo.dev/install.sh | shThen generate an operator keypair:
ordo operator initThis prints your public key (hex) and operator ID. The public key bootstraps the orchestrator in the next step; the private key stays in the operator data directory and is never shared. If you lose the public key, print it again with:
ordo operator whoami2. Set up the orchestrator
Section titled “2. Set up the orchestrator”On the orchestrator host, install the orchestrator:
curl -fsSL https://getordo.dev/install.sh | sh -s -- ordo-orchestratorConfirm where it landed — the systemd unit below references /usr/local/bin:
which ordo-orchestratorCreate the configuration directory and an orchestrator.yaml. Start from the
template below — every option shows its default, commented out unless it must be
set. Paste your public key from step 1 into bootstrap_key.
sudo mkdir -p /etc/ordo# 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 recordsInstall the unit file, then enable and start it:
[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.targetsudo systemctl daemon-reloadsudo systemctl enable --now ordo-orchestratorjournalctl -u ordo-orchestrator -fA first-run failure is almost always a missing or invalid bootstrap_key /
bootstrap_username.
3. Connect an agent
Section titled “3. Connect an agent”On the machine you want to manage, install the agent:
curl -fsSL https://getordo.dev/install.sh | sh -s -- ordo-agentCreate an agent.yaml. The defaults are sensible — the file is mostly a place
to opt into the remote terminal later:
# 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 samplesInstall the agent unit, replacing ORCHESTRATOR_HOST with your orchestrator’s
address:
[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.targetsudo systemctl daemon-reloadsudo systemctl enable --now ordo-agentjournalctl -u ordo-agent -fOn first connection the agent pins the orchestrator’s key and enters the Pending state on the orchestrator, awaiting your approval.
4. Approve and tag the agent
Section titled “4. Approve and tag the agent”Back on your workstation, list agents, approve the pending one, and tag it so state can target it later:
ordo agentsordo agents approve <node-id> --name client-01ordo agents tag client-01 group=home5. Open the web UI
Section titled “5. Open the web UI”Create a connection profile pointing at the orchestrator. The first profile you create automatically becomes the default, so the CLI uses it with no further configuration:
ordo profile create home --host <orchestrator-host>Then mint a web UI session and open the printed URL:
ordo web-loginIt prints a login token and a
https://<orchestrator-host>:4748/ui/auth/callback?token=… URL — open it in a
browser to reach the UI authenticated as your operator.
Next steps
Section titled “Next steps”Your fleet is connected and managed. From here you can author a state module and apply it to the agent’s tags — see the Reference for the state file format and CLI, and the Deployment templates for the raw configuration and unit files.