Skip to content

English

This runbook turns Hetzner VMs that already exist into observable nodes in the Control Plane: metrics must be pushed to POST /internal/server-metrics. The Worker does not poll the Hetzner Cloud API.

Prerequisites

  • D1 row in nodes for the VM with a stable node_id, region (sg | us | eu), and host (IP or DNS used for SSH).
  • INTERNAL_API_KEY (same value as the Control Plane Worker secret) available only on the node or in a secure runner — never committed to git.

Cadence

Payload fields

FieldRequiredNotes
node_idYesMust match nodes.node_id exactly.
cpu_pct, memory_pct, disk_pctNo0–100; omit or null if unknown.
tenant_countNoDefaults to 0; should reflect live tenants on that node for placement quality.
save_snapshotNoWhen true, also inserts into server_metrics_snapshots (if migration applied).
sourceNoe.g. node_push (default) or hetzner_api when a sidecar script pulls from Hetzner and forwards.

Tenant count (tenant_count)

  • Goal: count of tenant sites or workloads scheduled on this node (Frappe sites, containers, or your chosen definition).
  • Operational rule: document one method per environment (e.g. SQL against MariaDB metadata, bench --site all list, or automation that matches your stack). Reconcile periodically with tenants_master placement if applicable.

Standard deployment options

  1. systemd timer or cron on the node invoking a small script (see server-metrics-collection for a curl example).
  2. Ansible role that installs the timer and script when the server is provisioned.
  3. Optional: a scheduled job (e.g. GitHub Actions) that runs outside the Control Plane Worker, uses HCLOUD_TOKEN to list servers and map them to node_id, computes or proxies metrics, then calls the same POST endpoint. Keep Hetzner tokens out of the Worker (see prego-control-plane AGENTS).

Failure modes

SymptomCauseAction
No row in server_metrics for a nodePush never ran or key wrongFix cron/timer; verify Bearer and URL.
Stale updated_atPush stoppedAlert on freshness; restore agent.
Placement ignores loadtenant_count always 0Fix tenant counting script.

Related


한국어

목적

Hetzner에 이미 존재하는 VM을 Control Plane에서 관측 가능한 노드로 만들기 위한 운영 절차입니다. 메트릭은 푸시(POST /internal/server-metrics)만 지원하며, Worker가 Hetzner Cloud API를 주기적으로 조회하지는 않습니다.

전제 조건

  • 해당 VM이 D1 nodes에 등록되어 있고, node_id·region·host가 확정되어 있을 것.
  • INTERNAL_API_KEY는 노드(또는 안전한 실행기)에만 보관하고, 저장소에 넣지 않습니다.

주기·필드

테넌트 수 (tenant_count)

  • 해당 노드에 실제로 올라간 테넌트(사이트) 수를 반영해야 배치(decidePlacement) 품질이 올라갑니다.
  • 환경마다 산출 방식을 하나로 정하고(예: Frappe 사이트 목록, DB 쿼리), 운영 문서에 남깁니다.

배포 방식

  1. 노드에 cron/systemd로 스크립트 설치.
  2. 프로비저닝 시 Ansible로 동일 절차 자동화.
  3. (선택) Hetzner API는 CP Worker가 아닌 별도 스크립트·CI에서만 사용하고, 결과는 동일 엔드포인트로 푸시.

장애 대응

  • 메트릭이 비어 있으면 포화 판단·배치가 약해질 수 있으므로, 푸시 실패 알림과 updated_at 기준 신선도 점검을 권장합니다.

관련 문서: Hetzner node ID 매핑, 완료 정의(DoD)

Help