Trigger: deploy run#437/439 валился на bookva-ops-mcp restart-loop. Hot-fix `bookva-overlay 437d024` (idle-stub command) выкачен как interim — deploy run#440 зелёный. User ideology clarification: books VDS = наш host, slovo/bookva = клиентские стэки, ops-mcp host-level (один экземпляр на VDS, не per-tenant). Tracker capture'ит 10-step playbook + 5 design Qs (где жить host compose, deploy mechanism, MARIADB_PASSWORD scope, config volume path, audit прочих host-level кандидатов). hot-fix temporary до promote. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.5 KiB
books-ops-mcp-host-promote
Promote books-docker-proxy-ro + books-ops-mcp из slovo's stack в host-level stack на books VDS. Дропнуть idle-stub bookva-ops-mcp. Идеология: books VDS = наш host, slovo/bookva = клиентские tenant-стеки; ops-mcp видит host-wide docker socket → один экземпляр на VDS, не per-tenant.
Контекст / триггер
В сессии 2026-05-26 auto-deploy tenant=all упал на bookva-ops-mcp not running (state=restarting). Hot-fix — добавлен command: ["tail","-f","/dev/null"] в bookva-overlay/deploy/ops-mcp.compose.yml (commit 437d024), контейнер стал idle-stub без proxy/creds → deploy зелёный, MCP non-functional у bookva tenant'а. User отверг этот long-term shape: "books VDS — наш хост, slovo и bookva — клиентские стэки приложений".
Current legacy layout (наследие времени когда books-* совпадало и с host, и с единственным tenant'ом):
books/deploy/ops-mcp.compose.ymlсодержит два сервиса:books-docker-proxy-ro(host-level docker socket gateway) +books-ops-mcp(host-wide observability MCP). Deploy'ится через CI как часть slovo-tenant pipeline.bookva-overlay/deploy/ops-mcp.compose.yml— idle-stub без функциональности, deployed via tenant=bookva pipeline.
Target state
- Новый host-level stack (имя tentative —
books-ops) сbooks-docker-proxy-ro+books-ops-mcp. Namingbooks-*сохраняется потому что books = имя хоста, не tenant. - Stack живёт в Portainer на books VDS как management-plane (как
traefik+portainerсейчас — anti-pattern по project-discipline portainer rule, но user уже сделал исключение для management plane). - Deploy pipeline отдельный от tenant deploy (либо
deploy-host.ymlвvictor/books, либо manual через Portainer как traefik/portainer). bookva-ops-mcpstack удалён из Portainer + secretPORTAINER_STACK_ID_BOOKVA_OPS_MCPотозван из Gitea +bookva-overlay/deploy/ops-mcp.compose.ymlудалён +ops-mcpубран из tenant=bookva service list вbooks/.gitea/workflows/deploy.yml.- Slovo's
books/deploy/ops-mcp.compose.ymlлибо удалён, либо превращён в pointer на host-level (slovo больше не owns эти контейнеры).
Open design questions
-
Где жить host-level compose?
- (a)
.admin/host-stacks/books-vds/ops-mcp.compose.yml(private ops-репо, единая точка для host-level VDS configs). - (b) Новый
victor/books-vds-hostрепо. - (c)
victor/books/deploy/host/ops-mcp.compose.yml(рядом, но другой sub-pipeline). - Recommendation: (a) —
.admin/уже private + ops-flavored, host configs естественно ложатся рядом с.tasks/и.wiki/concepts/portainer-stack-management-vds.md.
- (a)
-
Как deploy'ить?
- Через CI: новый
deploy-host.ymlworkflow в.admin/(или в books). Trigger: workflow_dispatch + push на host-stacks/. - Manual через Portainer UI: matches current
traefik/portainerexception. User уже зафиксировал исключение из portainer-rule для management plane. - Recommendation: manual — management plane уже исключение, не плодим CI poll специально для одного stack'а.
- Через CI: новый
-
MARIADB_PASSWORD scope. Сейчас slovo's books-ops-mcp получает
MARIADB_PASSWORD(slovo's books-db root). Host-level ops-mcp должен видеть обе tenant DBs?- Если yes: env превращается в
SLOVO_MARIADB_PASSWORD+BOOKVA_MARIADB_PASSWORD, MCP lib/server.js должен поддержать обе connection strings (probably TENANT param per query). - Если no (ops-mcp работает только с docker, без DB): drop
MARIADB_PASSWORDenv вообще, MCP не делает DB-queries. - Check actual usage in
books-ops-mcppackage source — нужно прочитатьvictor/books/packages/ops-mcp/чтобы понять что server.js делает с MARIADB_PASSWORD.
- Если yes: env превращается в
-
Config volume. Сейчас mount
/opt/books/books-ops-mcp/config/default.json→ MCP config. Host-level — тот же path или/opt/books-vds-ops/config/default.json(если хочется убрать books- prefix как tenant-namespace)? -
Какие ещё host-level контейнеры спрятаны в slovo stack? Полезно одним проходом аудит сделать. Текущие host-level (по моему знанию):
traefik,portainer. Возможные кандидаты на промоушн:ntfy(push.kzntsv.site — single endpoint per VDS), backup-cron'ы. См. infra-inventory.md — частично пересекается.
Acceptance
- Новый stack (
books-opsили similar) running на books VDS, containsbooks-docker-proxy-ro+books-ops-mcp, healthy. bookva-ops-mcpstack удалён из Portainer, secret отозван, compose-файл удалён из bookva-overlay.ops-mcpservice исключён из tenant=bookva pipeline вbooks/.gitea/workflows/deploy.yml(либо tenant-loop, либо service-list).- Slovo's
books/deploy/ops-mcp.compose.ymlлибо удалён, либо ясно помечен как deprecated pointer. Slovo deploy pipeline больше не trying to deploy 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-dbetc).
Status
Status: ready
Where I stopped: not started — hot-fix bookva-overlay 437d024 (idle-stub bookva-ops-mcp) выкачен как interim, user явно подтвердил это temporary
Next action:
- Прочитать
victor/books/packages/ops-mcp/источник — понять что MCP реально делает сMARIADB_PASSWORD(resolves design Q3). - Принять design decisions Q1–Q5 (recommendation drafts выше).
- Создать host-level compose в выбранном месте.
- В Portainer: создать новый stack
books-ops(manual upload compose) → start → verifydocker exec books-ops-mcpworks. - В Portainer: stop + delete
bookva-ops-mcpstack. - В Gitea secrets: отозвать
PORTAINER_STACK_ID_BOOKVA_OPS_MCP. - В
victor/books/.gitea/workflows/deploy.yml: убратьops-mcpиз tenant=bookva service list (или изservices="api web job-scheduler ops-mcp"глобально + добавить host-level deploy в отдельный workflow). - В
victor/bookva-overlay:rm deploy/ops-mcp.compose.yml. - В
victor/books:rm deploy/ops-mcp.compose.yml(или превратить в README pointer). - Manual smoke:
mcp__books-ops__ops_docker_psвидит bookva-* containers.
Blocker: — Branch: master