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
nodesfor the VM with a stablenode_id,region(sg|us|eu), andhost(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
- Push every 1–5 minutes (aligned with server-metrics-collection).
Payload fields
| Field | Required | Notes |
|---|---|---|
node_id | Yes | Must match nodes.node_id exactly. |
cpu_pct, memory_pct, disk_pct | No | 0–100; omit or null if unknown. |
tenant_count | No | Defaults to 0; should reflect live tenants on that node for placement quality. |
save_snapshot | No | When true, also inserts into server_metrics_snapshots (if migration applied). |
source | No | e.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 withtenants_masterplacement if applicable.
Standard deployment options
- systemd timer or cron on the node invoking a small script (see server-metrics-collection for a curl example).
- Ansible role that installs the timer and script when the server is provisioned.
- 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 samePOSTendpoint. Keep Hetzner tokens out of the Worker (see prego-control-plane AGENTS).
Failure modes
| Symptom | Cause | Action |
|---|---|---|
No row in server_metrics for a node | Push never ran or key wrong | Fix cron/timer; verify Bearer and URL. |
Stale updated_at | Push stopped | Alert on freshness; restore agent. |
| Placement ignores load | tenant_count always 0 | Fix 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는 노드(또는 안전한 실행기)에만 보관하고, 저장소에 넣지 않습니다.
주기·필드
- 푸시 주기: 1~5분 권장.
- 필드 설명은 위 영문 표와 server-metrics-collection을 참고합니다.
테넌트 수 (tenant_count)
- 해당 노드에 실제로 올라간 테넌트(사이트) 수를 반영해야 배치(
decidePlacement) 품질이 올라갑니다. - 환경마다 산출 방식을 하나로 정하고(예: Frappe 사이트 목록, DB 쿼리), 운영 문서에 남깁니다.
배포 방식
- 노드에 cron/systemd로 스크립트 설치.
- 프로비저닝 시 Ansible로 동일 절차 자동화.
- (선택) Hetzner API는 CP Worker가 아닌 별도 스크립트·CI에서만 사용하고, 결과는 동일 엔드포인트로 푸시.
장애 대응
- 메트릭이 비어 있으면 포화 판단·배치가 약해질 수 있으므로, 푸시 실패 알림과
updated_at기준 신선도 점검을 권장합니다.
관련 문서: Hetzner node ID 매핑, 완료 정의(DoD)