tasks(books-ops-mcp-host-promote): 🟢 closed + host-stacks compose canonical

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) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 14:04:15 +03:00
parent e82b9a905f
commit 10e80dc036
4 changed files with 107 additions and 18 deletions

View File

@@ -1,14 +1,16 @@
--- ---
_last_updated_: 2026-05-26T23:55:00+03:00 _last_updated_: 2026-05-27T00:30:00+03:00
session_id: 2026-05-26-ops-mcp-host-promote-track session_id: 2026-05-26-ops-mcp-host-promote-CLOSED
--- ---
# Next session handoff # Next session handoff
## Recent commits ## 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 - `victor/books ae3ab14` — feat(deploy): ops-mcp host-promote — drop tenant pipeline (deploy.yml + delete ops-mcp.compose.yml)
- `.admin × 1` — tasks: завести `books-ops-mcp-host-promote` ⚪ + refresh handoff - `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) - `.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/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) - `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 | | Трек | Готовность | 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` | | `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-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 | | `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'а ## Спроси 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 те же». Когда? - **Manual heads-up учредителю Bookva** (Step 6 substitute) — отправить ей сообщение «Bookva теперь на `https://bookseller.kzntsv.site`, login те же». Когда?
- **`books-api-shutdown`** через 24-48ч — ad-hoc через Portainer или tracker task? - **`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 навсегда? - **`bookva-ozon-mcp-image-build`** — нужен build в victor/books CI? Сейчас image отсутствует, bookva-ozon-mcp stack не создан. Если service не используется — skip навсегда?

View File

@@ -1,4 +1,6 @@
# Admin Task Board # 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 (поздний вечер) — заведена `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._ _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. **Commits:** `victor/books ae3ab14` + `victor/bookva-overlay 50f5bbb` + `.admin` (this commit).
**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 Q1Q5 decisions → Portainer host-stack create → bookva-ops-mcp delete → secret revoke → deploy.yml service list edit → 2 compose-files rm → smoke).
**Blocker:**
**Branch:** master **Branch:** master
<!-- created-by: vitya / 2026-05-26 / trigger: deploy run#437/439 fail + user ideology clarification --> <!-- created-by: vitya / 2026-05-26 / trigger: deploy run#437/439 fail + user ideology clarification -->
<!-- closed-by: vitya / 2026-05-26 / Portainer in-place PUT stack 26 + delete stack 43 + 2 secrets revoked + 3 commits -->
--- ---

View File

@@ -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` сохранено). - `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). - 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 🟢 Closed одну сессию следом за заведением. **Решение design Qs:**
**Where I stopped:** not started — hot-fix `bookva-overlay 437d024` (idle-stub bookva-ops-mcp) выкачен как interim, user явно подтвердил это temporary - **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:** **Next action:**
1. Прочитать `victor/books/packages/ops-mcp/` источник — понять что MCP реально делает с `MARIADB_PASSWORD` (resolves design Q3). 1. Прочитать `victor/books/packages/ops-mcp/` источник — понять что MCP реально делает с `MARIADB_PASSWORD` (resolves design Q3).
2. Принять design decisions Q1Q5 (recommendation drafts выше). 2. Принять design decisions Q1Q5 (recommendation drafts выше).

View File

@@ -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