diff --git a/NODA1-SAFE-DEPLOY.md b/NODA1-SAFE-DEPLOY.md new file mode 100644 index 00000000..2ce39f9a --- /dev/null +++ b/NODA1-SAFE-DEPLOY.md @@ -0,0 +1,71 @@ +# NODA1 Safe Deploy (Canonical Workflow) + +**Goal:** синхронізувати ноут ↔ GitHub ↔ NODA1 ↔ реальний Docker-стек так, щоб не ламати працюючий прод і не плодити "невидимі" гілки. + +**Canonical source of truth:** GitHub `origin/main`. + +--- + +## Ролі директорій на NODA1 + +- `/opt/microdao-daarion` — legacy checkout (може мати роз'їхавшу історію). Не використовувати для `git pull/rebase`, якщо є конфлікти. +- `/opt/microdao-daarion.repo` — canonical deployment checkout (git worktree на `origin/main`). Деплой робимо тільки звідси. + +--- + +## Golden rules + +1. Жодних ручних правок коду/доків на NODA1 (крім аварійного hotfix з наступним PR). +2. Жодних гілок/розробки на NODA1. +3. Docker compose завжди з однаковим project name: `-p microdao-daarion`. +4. Secrets не комітяться; для них тримати `*.example` + короткий опис розміщення. + +--- + +## Safe sync (NODA1) + +```bash +ssh root@144.76.224.179 + +cd /opt/microdao-daarion +git fetch origin + +cd /opt/microdao-daarion.repo +git pull --ff-only +git rev-parse --short HEAD +``` + +--- + +## Safe deploy одного сервісу (мінімальний ризик) + +### Router + +```bash +cd /opt/microdao-daarion.repo + +docker compose -p microdao-daarion -f docker-compose.node1.yml build router +docker compose -p microdao-daarion -f docker-compose.node1.yml up -d --no-deps --force-recreate router + +curl -fsS http://127.0.0.1:9102/health +``` + +### Gateway + +```bash +cd /opt/microdao-daarion.repo + +docker compose -p microdao-daarion -f docker-compose.node1.yml build gateway +docker compose -p microdao-daarion -f docker-compose.node1.yml up -d --no-deps --force-recreate gateway + +curl -fsS http://127.0.0.1:9300/health +``` + +--- + +## Runtime snapshot + +```bash +cd /opt/microdao-daarion.repo +./scripts/node1/snapshot_node1.sh > "/opt/backups/node1_snapshot_$(date +%Y%m%d-%H%M%S).txt" +``` diff --git a/PROJECT-MASTER-INDEX.md b/PROJECT-MASTER-INDEX.md index 55c182cd..5e8f1896 100644 --- a/PROJECT-MASTER-INDEX.md +++ b/PROJECT-MASTER-INDEX.md @@ -26,6 +26,19 @@ | **Project Root** | `/opt/microdao-daarion/` | | **Docker Network** | `dagi-network` | + +### NODA1 Sync Policy (Repo ↔ Runtime) + +**Канонічна правда:** GitHub `origin/main`. + +На NODA1: +- `/opt/microdao-daarion.repo` — canonical deployment checkout (git worktree на `origin/main`), деплой робимо тільки звідси. +- `/opt/microdao-daarion` — legacy checkout; не використовувати для `git pull/rebase`, якщо історія роз'їхалась. + +**Safe deploy runbook:** `NODA1-SAFE-DEPLOY.md` + +**Runtime snapshot:** `scripts/node1/snapshot_node1.sh` + --- ## 🎯 AGENT REGISTRY (Single Source of Truth) diff --git a/scripts/node1/snapshot_node1.sh b/scripts/node1/snapshot_node1.sh new file mode 100755 index 00000000..ac03b934 --- /dev/null +++ b/scripts/node1/snapshot_node1.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -euo pipefail + +TS=$(date -u +%Y-%m-%dT%H:%M:%SZ) + +echo "=== NODE1 SNAPSHOT ===" +echo "timestamp_utc: $TS" + +echo "" +echo "--- git (deployment checkout) ---" +if [ -d "/opt/microdao-daarion.repo/.git" ]; then + cd /opt/microdao-daarion.repo + echo "path: /opt/microdao-daarion.repo" + echo "head: $(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" + echo "branch: $(git branch --show-current 2>/dev/null || echo 'detached')" + echo "status:" + git status -sb 2>/dev/null || true +else + echo "WARN: /opt/microdao-daarion.repo not found" +fi + +echo "" +echo "--- docker ps (top 30) ---" +docker ps --format "table {{.Names}} {{.Status}} {{.Image}}" | head -30 + +echo "" +echo "--- health endpoints ---" +for u in "http://127.0.0.1:9102/health" "http://127.0.0.1:9300/health" "http://127.0.0.1:8000/health" "http://127.0.0.1:6333/healthz" ; do + code=$(curl -sS -m 3 -o /dev/null -w "%{http_code}" "$u" || true) + echo "$u => $code" +done + +echo "" +echo "--- docker inspect (images + compose project) ---" +for c in dagi-router-node1 dagi-gateway-node1 dagi-memory-service-node1; do + if docker inspect "$c" >/dev/null 2>&1; then + img=$(docker inspect -f '{{.Config.Image}}' "$c" 2>/dev/null || true) + prj=$(docker inspect -f '{{ index .Config.Labels "com.docker.compose.project" }}' "$c" 2>/dev/null || true) + echo "$c image=$img compose_project=$prj" + else + echo "$c not_found" + fi +done