Skip to Content

Headless server deployment

Production servers, CI runners, build VMs — anywhere there’s no GUI but you still want CMDOP. This guide covers install, daemonize, verify, and the usual gotchas.

Prerequisites

  • 64-bit Linux, macOS, or Windows.
  • Outbound HTTPS to the CMDOP relay (no inbound ports needed).
  • An OAuth login or a workspace API key.

Step 1 — install the agent

Linux / macOS:

curl -fsSL https://cmdop.com/install.sh | sh

For unattended provisioning (no interactive prompts):

curl -fsSL https://cmdop.com/install.sh | sh -s -- --no-prompt

The installer drops the cmdop binary into /usr/local/bin/ (or ~/.local/bin/ for unprivileged installs).

Step 2 — authenticate

Two paths:

API key (recommended for headless):

cmdop connect key set "$CMDOP_API_KEY" --workspace acme-prod

OAuth (interactive):

cmdop login --headless # Open the URL on a different machine to complete device flow.

API keys survive member churn and don’t need refresh — better fit for headless.

Step 3 — register the machine

cmdop connect

The agent registers under the OS hostname by default. Override with --name if you want a friendly label distinct from hostname.

Step 4 — daemonize

Linux (systemd)

Create /etc/systemd/system/cmdop-agent.service:

[Unit] Description=CMDOP agent After=network-online.target Wants=network-online.target [Service] Type=simple User=cmdop ExecStart=/usr/local/bin/cmdop agent start --foreground Restart=on-failure RestartSec=5 Environment="CMDOP_API_KEY=replace-me-or-load-from-credentials-store" [Install] WantedBy=multi-user.target

Then:

sudo systemctl daemon-reload sudo systemctl enable --now cmdop-agent sudo systemctl status cmdop-agent

macOS (launchd)

CMDOP includes a launchd template:

cmdop service install # writes ~/Library/LaunchAgents/com.cmdop.agent.plist cmdop service start

Windows

cmdop service install Start-Service cmdop-agent

Step 5 — verify

cmdop agent status

Expect ONLINE and a recent heartbeat. From another machine:

cmdop connect --list # headless-server-01 ONLINE 2s ago cmdop connect headless-server-01 exec 'uname -a'

Step 6 — set permissions for headless

Without an attached UI, asks would time out and end up denied. Two safe choices:

# Strict + explicit allowlist cmdop permissions mode strict cmdop permissions allow 'execute_command(systemctl status *)' cmdop permissions allow 'read_file(/var/log/**)'

Or:

# Bypass for fully trusted sandbox VMs only cmdop permissions mode bypass

See Modes for the full picture.

Logs

cmdop agent logs -f

Logs live at <LogDir>/agent.log (lumberjack-rotated by size, 10 MB × 5 files). For external shipping see Log rotation.

Updates

cmdop update

Or enable auto-update — see Auto-update.

Common pitfalls

  • No outbound HTTPS — the agent can’t reach the relay. Open egress to *.cmdop.com:443.
  • PATH issues under systemd — use absolute paths for the binary.
  • Missing userUser=cmdop must exist; create with useradd -r -s /sbin/nologin cmdop or run as your existing service user.
  • API key not loaded — read from a credentials manager (HashiCorp Vault, AWS Secrets Manager) rather than embedding in the unit file.

Treat the workspace API key like a database password. Use a secrets store or systemd credentials, not a literal Environment= line in version control.

The daemon talks outbound only. No inbound port needs to open. CGNAT, restrictive corporate firewalls, and behind-NAT laptops all work.

Last updated on