From 10e80dc036e38f022eff255f70eb5c7a5670a2d6 Mon Sep 17 00:00:00 2001 From: vitya Date: Tue, 26 May 2026 14:04:15 +0300 Subject: [PATCH] =?UTF-8?q?tasks(books-ops-mcp-host-promote):=20?= =?UTF-8?q?=F0=9F=9F=A2=20closed=20+=20host-stacks=20compose=20canonical?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stack 26 (books-ops-mcp) in-place PUT в host-level compose без container churn. Stack 43 (bookva-ops-mcp) deleted. 2 Gitea secrets revoked. New canonical: `host-stacks/books-vds/ops-mcp.compose.yml` (management-plane, manual Portainer updates как traefik/portainer). Design locks: location=.admin/host-stacks, deploy=manual Portainer, MariaDB scope=slovo's only (Option A), config path unchanged. Companion commits: `victor/books ae3ab14`, `victor/bookva-overlay 50f5bbb`. Co-Authored-By: Claude Opus 4.7 (1M context) --- .tasks/NEXT_SESSION.md | 14 +++-- .tasks/STATUS.md | 16 +++--- .tasks/books-ops-mcp-host-promote.md | 28 +++++++++- host-stacks/books-vds/ops-mcp.compose.yml | 67 +++++++++++++++++++++++ 4 files changed, 107 insertions(+), 18 deletions(-) create mode 100644 host-stacks/books-vds/ops-mcp.compose.yml diff --git a/.tasks/NEXT_SESSION.md b/.tasks/NEXT_SESSION.md index 79be211..6a1f79e 100644 --- a/.tasks/NEXT_SESSION.md +++ b/.tasks/NEXT_SESSION.md @@ -1,14 +1,16 @@ --- -_last_updated_: 2026-05-26T23:55:00+03:00 -session_id: 2026-05-26-ops-mcp-host-promote-track +_last_updated_: 2026-05-27T00:30:00+03:00 +session_id: 2026-05-26-ops-mcp-host-promote-CLOSED --- # Next session handoff ## Recent commits -- `victor/bookva-overlay 437d024` — fix(deploy): bookva-ops-mcp idle-stub command (tail -f /dev/null) — hot-fix deploy run#437/439 restart-loop fail; interim до host-promote -- `.admin × 1` — tasks: завести `books-ops-mcp-host-promote` ⚪ + refresh handoff +- `victor/books ae3ab14` — feat(deploy): ops-mcp host-promote — drop tenant pipeline (deploy.yml + delete ops-mcp.compose.yml) +- `victor/bookva-overlay 50f5bbb` — chore(deploy): drop ops-mcp.compose.yml (host-promoted в .admin) +- `victor/bookva-overlay 437d024` — fix(deploy): bookva-ops-mcp idle-stub command (interim, теперь obsolete) +- `.admin × 2` — tasks `books-ops-mcp-host-promote` 🟢 closed + handoff refresh + new `host-stacks/books-vds/ops-mcp.compose.yml` - `.wiki b2528fb` — wiki(concepts): ingest 3 generic ops-gotchas from bookva tenant-split (manual write, MCP commitFile bug) - `victor/books c434230` — deploy.yml: auto-deploy default tenant=slovo → all (symmetric rollout active) - `victor/bookva-overlay 2862279` — traefik labels: entrypoints=https + certresolver=letsEncrypt (books-VDS instance naming) @@ -39,7 +41,7 @@ session_id: 2026-05-26-ops-mcp-host-promote-track | Трек | Готовность | Entry-point | |---|---|---| -| `books-ops-mcp-host-promote` ⚪ (NEW) | promote ops-mcp+docker-proxy в host-level stack, drop bookva-ops-mcp idle-stub. Ideology: books VDS = host, slovo/bookva = tenant-стэки. 10-step playbook + 5 design Qs. | `.tasks/books-ops-mcp-host-promote.md` | +| `books-ops-mcp-host-promote` 🟢 **closed** — see Recent commits below | n/a | | `books-api-shutdown` (NEW micro-task) | 24-48h soak ends ~2026-05-27/28. `docker stop books-api` через Portainer | TBD `.tasks/books-api-shutdown.md` | | `bookva-ozon-mcp-image-build` (NEW micro-task) | image `books-ozon-mcp:master` не в registry — нужен build pipeline в victor/books | TBD `.tasks/bookva-ozon-mcp-image-build.md` | | `bookva-tenant-cutover` task **не понадобилась** — cutover de-facto произошёл в этой сессии (Step 6 descoped по решению user'а) | n/a — manual heads-up учредителю Bookva | @@ -53,7 +55,7 @@ session_id: 2026-05-26-ops-mcp-host-promote-track ## Спроси user'а -- **`books-ops-mcp-host-promote`** — приоритет («ближайшее время» сказано). Когда начинать? Сначала read books/packages/ops-mcp/server.js чтобы разрешить design Q3 (MARIADB_PASSWORD scope — один tenant DB или обе). +- **Multi-tenant DB observability через ops-mcp** (deferred design call) — нужно ли видеть bookva-db / bookva-mongo через MCP? Если да — extend lib (per-tenant pool array) ИЛИ drop DB tools оставив только docker. - **Manual heads-up учредителю Bookva** (Step 6 substitute) — отправить ей сообщение «Bookva теперь на `https://bookseller.kzntsv.site`, login те же». Когда? - **`books-api-shutdown`** через 24-48ч — ad-hoc через Portainer или tracker task? - **`bookva-ozon-mcp-image-build`** — нужен build в victor/books CI? Сейчас image отсутствует, bookva-ozon-mcp stack не создан. Если service не используется — skip навсегда? diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 7e817b7..504ac08 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,4 +1,6 @@ # Admin Task Board +_Updated: 2026-05-26 (поздний вечер) — `books-ops-mcp-host-promote` 🟢 **closed** в ту же сессию следом за заведением. Stack 26 (books-ops-mcp) in-place PUT в host-level compose без container churn. Stack 43 (bookva-ops-mcp) deleted. 2 Gitea secrets revoked. `victor/books ae3ab14` + `victor/bookva-overlay 50f5bbb` + `.admin` host-stacks/books-vds/ops-mcp.compose.yml. ops-mcp теперь management-plane (manual Portainer)._ + _Updated: 2026-05-26 (поздний вечер) — заведена `books-ops-mcp-host-promote` ⚪ (deploy run#437/439 валился на bookva-ops-mcp restart-loop → hot-fix `bookva-overlay 437d024` idle-stub interim → user ideology «books VDS = host, slovo/bookva = клиентские стэки» → promote `books-docker-proxy-ro`+`books-ops-mcp` в host-level stack, drop bookva-ops-mcp). Deploy run#440 зелёный._ _Updated: 2026-05-26 (поздний вечер) — `bookva-tenant-cutover-prep` 🟢 **closed** — 6/7 в одну сессию: Steps 1+2+3+4+5+7. Step 6 delayed по spec (1-2 нед до cutover). bookva-ozon-mcp deferred (image не в registry). MinIO bucket copy deferred (cutover-time). 9 bookva Portainer stacks created (3 active: db/mongo/es internal-only; 6 stopped pre-cutover). bookva-overlay 4 commits: templates+mariadb:10.6+mongo:4.2+api internal-only+depends_on removed._ @@ -46,20 +48,16 @@ _Updated: 2026-05-25 (`iis-migration-to-ruvds` 🟢 closed Phase 1 per user deci --- -## ⚪ [books-ops-mcp-host-promote] — promote `books-docker-proxy-ro` + `books-ops-mcp` в host-level stack, drop `bookva-ops-mcp` +## 🟢 [books-ops-mcp-host-promote] — closed 2026-05-26 — host-promote ops-mcp+docker-proxy в `.admin/host-stacks/books-vds/`, drop bookva-ops-mcp -**Идеология (user 2026-05-26):** books VDS = наш host, slovo/bookva = клиентские стэки приложений. Ops-mcp видит host-wide docker socket → один экземпляр на VDS, не per-tenant. +Stack 26 (books-ops-mcp) in-place PUT без container churn (env MARIADB_PASSWORD preserved). Stack 43 (bookva-ops-mcp) deleted. Gitea secrets `PORTAINER_STACK_ID_BOOKVA_OPS_MCP` + `PORTAINER_STACK_ID_OPS_MCP` revoked. ops-mcp убран из tenant=slovo|bookva pipeline (deploy.yml). Management-plane: image updates через Portainer UI manual. -**Текущее состояние:** `books-docker-proxy-ro` + `books-ops-mcp` живут в slovo's stack как legacy (когда books-* совпадало и с host, и с единственным tenant'ом). `bookva-ops-mcp` сейчас idle-stub (`bookva-overlay 437d024`, `command: tail -f /dev/null`) — deploy зелёный, MCP non-functional, interim до promote. +**Design locks (см. [books-ops-mcp-host-promote.md](books-ops-mcp-host-promote.md) § Closure note):** Q1 location=`.admin/host-stacks/`, Q2 deploy=manual Portainer, Q3 MariaDB scope=slovo's only (Option A), Q4 config volume path unchanged, Q5 audit прочих host-level кандидатов punt. -**Target:** новый host-level stack `books-ops` в Portainer на books VDS (management-plane как traefik+portainer), `bookva-ops-mcp` stack/secret/compose-файл удалены, slovo's ops-mcp.compose.yml dropped. - -**Status:** ready -**Where I stopped:** not started — hot-fix bookva idle-stub выкачен interim, design recommendations sketch'нуты -**Next action:** см. [books-ops-mcp-host-promote.md](books-ops-mcp-host-promote.md) § Next action (10 шагов: read packages/ops-mcp source → design Q1–Q5 decisions → Portainer host-stack create → bookva-ops-mcp delete → secret revoke → deploy.yml service list edit → 2 compose-files rm → smoke). -**Blocker:** — +**Commits:** `victor/books ae3ab14` + `victor/bookva-overlay 50f5bbb` + `.admin` (this commit). **Branch:** master + --- diff --git a/.tasks/books-ops-mcp-host-promote.md b/.tasks/books-ops-mcp-host-promote.md index 74d2d15..9e9e25a 100644 --- a/.tasks/books-ops-mcp-host-promote.md +++ b/.tasks/books-ops-mcp-host-promote.md @@ -49,10 +49,32 @@ Current legacy layout (наследие времени когда books-* сов - `ssh + docker exec -i books-ops-mcp node lib/server.js` продолжает работать (slovo's caller path не сломан, имя контейнера `books-ops-mcp` сохранено). - Smoke: MCP tool calls (например `mcp__books-ops__ops_docker_ps`) видят все tenant containers (`books-db`, `bookva-db`, `slovo-db` etc). -## Status +## Closure note (2026-05-26) -**Status:** ready -**Where I stopped:** not started — hot-fix `bookva-overlay 437d024` (idle-stub bookva-ops-mcp) выкачен как interim, user явно подтвердил это temporary +🟢 Closed одну сессию следом за заведением. **Решение design Qs:** +- **Q1 host compose location:** `.admin/host-stacks/books-vds/ops-mcp.compose.yml` (canonical, private ops-репо). +- **Q2 deploy mechanism:** manual через Portainer UI (как traefik/portainer — management plane exception). +- **Q3 MARIADB_PASSWORD scope:** Option A — host instance видит только slovo's books-db + slovo's Mongo. ops-mcp source connects к ОДНОМУ MariaDB pool и ОДНОМУ MongoClient; multi-tenant DB observability — design call отложен (если нужно: extend lib + separate pools per-tenant, либо drop DB tools оставив только docker). +- **Q4 config volume:** path unchanged (`/opt/books/books-ops-mcp/config/default.json` на host'е). Books-prefix остался — host = books VDS. +- **Q5 audit прочих host-level кандидатов:** punt, отдельная задача (kicks off `infra-inventory`). + +**Executed:** +- ✅ Read `books/packages/ops-mcp/{server,mariadb,mongo}.js` + `config/{default,custom-environment-variables}.json` — locked design Qs. +- ✅ Created `.admin/host-stacks/books-vds/ops-mcp.compose.yml` (host-level canonical). Image hardcoded `:master` (manual update, не env-var). +- ✅ Portainer stack 26 (books-ops-mcp) **in-place PUT** с новой compose. Containers `books-docker-proxy-ro` + `books-ops-mcp` остались running без recreate. Env `MARIADB_PASSWORD` preserved. +- ✅ Portainer stack 43 (bookva-ops-mcp) **deleted**. Container bookva-ops-mcp gone (404). +- ✅ `victor/books ae3ab14`: deploy.yml drop ops-mcp service + STACK_ID_*_OPS_MCP envs + healthcheck case; `deploy/ops-mcp.compose.yml` deleted. +- ✅ `victor/bookva-overlay 50f5bbb`: `deploy/ops-mcp.compose.yml` deleted (idle-stub no longer needed). +- ✅ Gitea secrets revoked: `PORTAINER_STACK_ID_BOOKVA_OPS_MCP` + `PORTAINER_STACK_ID_OPS_MCP`. `SLOVO_OPS_MCP` was never set (fallback chain used OPS_MCP). +- ✅ Smoke: `books-ops-mcp State=running`, `books-docker-proxy-ro State=running`, `bookva-ops-mcp` 404. + +**Open follow-ups (если возникнет потребность):** +- Multi-tenant DB observability через MCP — extend lib (per-tenant pool array, TENANT param на queries) ИЛИ drop DB tools оставив только docker. +- Stack name "books-ops-mcp" → "books-ops" в Portainer (cosmetic; rename требует recreate, не делал). +- Audit прочих host-level кандидатов (ntfy? backup-cron?) — через `infra-inventory`. + +**Status:** closed 2026-05-26 +**Where I stopped:** all 10 steps done; Stack id=26 промоутен в host-level семантически без container churn; bookva-side полностью удалён. **Next action:** 1. Прочитать `victor/books/packages/ops-mcp/` источник — понять что MCP реально делает с `MARIADB_PASSWORD` (resolves design Q3). 2. Принять design decisions Q1–Q5 (recommendation drafts выше). diff --git a/host-stacks/books-vds/ops-mcp.compose.yml b/host-stacks/books-vds/ops-mcp.compose.yml new file mode 100644 index 0000000..e0cda97 --- /dev/null +++ b/host-stacks/books-vds/ops-mcp.compose.yml @@ -0,0 +1,67 @@ +# books-ops — host-level observability stack на books VDS (89.253.255.133). +# +# Ideology: books VDS = наш host, slovo/bookva = клиентские tenant-стэки. +# Один host-wide ops-mcp видит все контейнеры через `tcp://books-docker-proxy-ro:2375`. +# +# Tenant DB scope (current): slovo's books-db + slovo's Mongo (per ops-mcp/config/default.json). +# Bookva-tenant DB observability через MCP — design call отложен (см. .tasks/books-ops-mcp-host-promote.md). +# +# Lifecycle: +# - Managed manually через Portainer UI (как traefik + portainer — management plane exception +# из портейнер-rule, не deploy'ится из tenant CI pipeline). +# - Update image tag: Portainer → Stack → Edit compose → change image tag → Update. +# - Container names books-docker-proxy-ro + books-ops-mcp **сохраняются** — +# .claude.json использует `ssh vps-books docker exec -i books-ops-mcp ...`. +# +# Если нужно поднять второй MCP instance (per-tenant DB observability) — отдельный stack, +# отдельные container names (bookva-ops-mcp / slovo-ops-mcp), отдельный config volume. + +services: + books-docker-proxy-ro: + container_name: books-docker-proxy-ro + image: tecnativa/docker-socket-proxy:0.3 + restart: unless-stopped + environment: + # Только read-методы на /containers/* — list, inspect, logs, stats. + # POST=0 (default) — никаких prune/start/stop/rm. Все остальные + # ресурсы (images, build, volumes, networks, exec, system, info) — 0. + CONTAINERS: 1 + POST: 0 + IMAGES: 0 + BUILD: 0 + EXEC: 0 + VOLUMES: 0 + NETWORKS: 0 + SERVICES: 0 + SYSTEM: 0 + INFO: 0 + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + networks: + - proxy + + books-ops-mcp: + container_name: books-ops-mcp + image: registry.kzntsv.site/books-ops-mcp:master + restart: unless-stopped + depends_on: + - books-docker-proxy-ro + environment: + NODE_ENV: production + TZ: Europe/Moscow + DOCKER_HOST: tcp://books-docker-proxy-ro:2375 + MARIADB_PASSWORD: ${MARIADB_PASSWORD} + volumes: + # ВНИМАНИЕ: на VPS файл /opt/books/books-ops-mcp/config/default.json + # должен существовать ДО первого старта стека, иначе Docker создаст + # пустую directory вместо файла. + - /opt/books/books-ops-mcp/config/default.json:/usr/src/app/packages/ops-mcp/config/default.json + networks: + - proxy + # Контейнер всегда живой; реальный MCP запускается per-session через + # ssh + docker exec -i books-ops-mcp node lib/server.js. CMD = idle. + command: ["tail", "-f", "/dev/null"] + +networks: + proxy: + external: true