@nitra/cnpg-backup
v1.0.0
Published
CNPG Barman backup monitoring: Cursor skill /n-cnpg-backup-pr, CronJob run-once, Alertmanager/Prometheus/S3
Maintainers
Readme
@nitra/cnpg-backup
npm-пакет для backup і моніторингу PostgreSQL на CloudNativePG з Barman Cloud plugin: генерація інфраструктурного PR у сервісному репо + періодичні перевірки в Kubernetes.
Один пакет закриває два сценарії:
- Cursor-сліл
/n-cnpg-backup-pr— шаблони YAML для PR (backup, PodMonitor, PrometheusRule, backup-monitor CronJob). - CLI
run-once— runner у CronJob: Alertmanager poll, Prometheus/S3, restore test, Telegram.
Еталон інтеграції — репозиторій contract (dev cluster-hasura у namespace dev-contract).
Для чого
| Задача | Як вирішує пакет |
| ------ | ---------------- |
| Налаштувати CNPG → GCS backup (Barman) | Скіл генерує ObjectStore, ScheduledBackup, patch Cluster |
| Алерти «backup застарів / failed / WAL lag» | PrometheusRule з label backup-monitor: "true" |
| Enrichment алертів (контекст WAL/S3, restore) | CronJob run-once опитує Alertmanager API |
| Restore test без ручного деплою | K8s restore у namespace сервісу (stateless) |
| Один PR у b2b/contract — без central copy-db service | ConfigMap target.yaml, без PostgreSQL backup_targets |
Не робить: не деплоїть у кластер сам (merge PR → CI apply-k8s); не замінює platform Alertmanager (generic route — один раз у platform).
Архітектура
┌─────────────────────────────────────────────────────────────┐
│ Developer: npx @nitra/cnpg-backup sync-skill │
│ Cursor: /n-cnpg-backup-pr │
└──────────────────────────┬──────────────────────────────────┘
│ YAML у сервісному репо
▼
┌─────────────────────────────────────────────────────────────┐
│ CNPG Cluster → GCS (Barman) │
│ PodMonitor → Prometheus → PrometheusRule → Alertmanager │
└──────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ CronJob backup-monitor (напр. */15 * * * *) │
│ npx @nitra/cnpg-backup run-once │
│ 1. GET Alertmanager /api/v2/alerts (backup-monitor=true) │
│ 2. Prometheus poll (опційно) │
│ 3. S3 poll (опційно) │
│ 4. restore test (throttled, напр. раз на 7 днів) │
└─────────────────────────────────────────────────────────────┘Alertmanager обробляється завжди через CronJob (poll API), окремий HTTP Deployment/webhook у namespace сервісу не потрібен.
Що потрапляє в сервісний репо (після скілу)
| Шлях | Призначення |
| ---- | ----------- |
| k8s/db/dev/backup/ | ObjectStore, ScheduledBackup, once |
| k8s/db/dev/cnpg-podmonitor.yaml | метрики Barman plugin |
| k8s/monitoring/prometheus-rules-cnpg-backup.yaml | алерти SLA/RPO/WAL |
| k8s/db/dev/backup-monitor/configmap.yaml | target.yaml (stateless config) |
| k8s/db/dev/backup-monitor/cronjob.yaml | runner (run-once) + env |
| k8s/db/dev/backup-monitor/configmap.yaml | target.yaml (storageType: gcs, …) |
Конфіг target — ConfigMap, не SQL. Test plan — лише в описі GitHub PR (без .md у k8s/).
Встановлення в consumer-репо (contract, b2b, …)
bun add -d @nitra/cnpg-backup
npx @nitra/cnpg-backup sync-skill
# Cursor: /n-cnpg-backup-prУ .n-cursor.json:
{
"skills": ["cnpg-backup-pr"]
}Якщо є @nitra/cursor:
npx @nitra/cursorпідтягне скіл з node_modules/@nitra/cnpg-backup/skills/cnpg-backup-pr/.
CronJob (production)
Після merge PR у git і apply-k8s:
command:
- npx
- --yes
- "@nitra/[email protected]"
- run-onceОбовʼязкові env (CronJob + ConfigMap):
| Змінна | Призначення |
| ------ | ----------- |
| STATELESS_MODE | true |
| BACKUP_TARGET_CONFIG_PATH | /etc/backup-monitor/target.yaml |
| RESTORE_EXECUTOR | k8s (restore у pod, без Docker) |
| ALERTMANAGER_BASE_URL | URL Alertmanager |
| PROMETHEUS_BASE_URL | URL Prometheus (якщо PROMETHEUS_MONITOR_ENABLED=true) |
| MONITOR_ENABLED | false для GCS+WI (без S3 poll) |
ALERTMANAGER_POLL_ENABLED — за замовчуванням true при STATELESS_MODE=true (можна не задавати).
Restore test: за замовчуванням увімкнено (RESTORE_TEST_ENABLED default true), throttle — restoreTestIntervalDays у target (default 7 днів). Вимкнути restore в CronJob: RESTORE_TEST_ENABLED=false.
GCS (maya-backup): у target.yaml потрібні storageType: gcs, s3Endpoint: https://storage.googleapis.com, s3Region: auto; pod SA з WI на bucket. Перевірка читання:
# у pod з тим самим serviceAccount, що CronJob:
npx @nitra/[email protected] verify-gcsЛокально (з ADC / gcloud auth application-default login):
STATELESS_MODE=true BACKUP_TARGET_CONFIG_PATH=./fixtures/target-gcs.example.yaml bun run verify-gcsОбраз CronJob: node:24-alpine (+ postgresql18 для restore, див. шаблон cronjob).
CLI
npx @nitra/cnpg-backup <command>| Команда | Де використовується | Runtime |
| ------- | ------------------- | ------- |
| sync-skill | локально / CI setup | Node |
| run-once | K8s CronJob | Node ≥24 |
| restore-test | ручний restore (throttle як у CronJob) | Node |
| verify-gcs | перевірка list/download prefix у GCS | Node (WI / ADC) |
Production: sync-skill + run-once.
Programmatic API
import {
createApp,
runOnceCycle,
loadBackupTargetFromEnv,
BackupTargetConfigFileSchema,
monitoringConfig
} from '@nitra/cnpg-backup'
const exitCode = await runOnceCycle()Зміст npm-пакета
| Каталог | Що всередині |
| ------- | ------------ |
| skills/cnpg-backup-pr/ | SKILL.md + YAML/Markdown шаблони PR |
| src/ | runner (Alertmanager, Prometheus, S3, restore, Telegram) |
| bin/cnpg-backup.js | CLI entry |
| scripts/sync-cursor-skill.mjs | копіювання скілу в .cursor/skills/ |
Розробка цього репо
bun i
bun test
bun run run-once # локально (потрібен .env або stateless ConfigMap)
bun run sync-skill # у корені consumer-репо: --cwd ../contractВимоги: Node ≥24, Bun ≥1.3 (bun test, bun run verify-gcs).
Міграція з @nitra/copy-db
Пакет @nitra/copy-db deprecated. Заміни:
| Було | Стало |
| ---- | ----- |
| npx @nitra/copy-db sync-skill | npx @nitra/cnpg-backup sync-skill |
| npx @nitra/copy-db run-once | npx @nitra/cnpg-backup run-once |
| {{COPY_DB_NPM_VERSION}} у шаблонах | {{CNPG_BACKUP_NPM_VERSION}} |
Репозиторій github.com/nitra/copy-db лишається для lab/legacy SQL.
Publish на npm (Trusted Publisher)
CI: .github/workflows/npm-publish.yml — push у main (зміни npm/**). Без NPM_TOKEN — лише OIDC; release через n-cursor release.
Одноразово на npmjs.com
- Org
@nitra: Packages → Create scoped package@nitra/cnpg-backup(якщо 404 на publish — пакет ще не створений). - Package Settings → Publishing access → Add GitHub Actions (Trusted Publisher):
- Repository:
nitra/cnpg-backup - Workflow filename:
npm-publish.yml - Environment: (порожньо)
- Repository:
- Push у
mainзі зміноюnpm/**→ workflow release + publish (JS-DevTools/npm-publish, provenance).
Перевірка:
npm view @nitra/cnpg-backup versionПеревірка restore / GCS у dev-кластері (contract)
Після apply backup-monitor у dev-contract:
kubectl -n dev-contract create job --from=cronjob/backup-monitor backup-monitor-verify-gcs-$(date +%s) --dry-run=client -o yaml \
| sed 's|exec npx.*run-once|exec npx --yes @nitra/[email protected] verify-gcs|' \
| kubectl apply -f -
kubectl -n dev-contract logs -f job/backup-monitor-verify-gcs-...Очікування: verify-gcs: OK, objects under prefix > 0. Для повного restore: npx … restore-test (довше, потрібен postgresql18 у образі).
Links
- Репозиторій: github.com/nitra/cnpg-backup
- Скіл (деталі placeholders):
skills/cnpg-backup-pr/SKILL.md - Platform Alertmanager:
skills/cnpg-backup-pr/template-alertmanager-route-snippet.md
