Files
admin/.tasks/books-vds-stacks-to-portainer.md
vitya 439da3cef6 tasks: add books-vds-stacks-to-portainer
Follow-up after books-vds-backup-daily-kreknin 🟢. User-requested:
migrate SSH-compose стеки (ES/mongo/minio/books-db/proxy-chain) под
Portainer-managed. Pattern reuse VDS-infra retro-migration script
(.wiki/concepts/portainer-stack-management-vds.md). Skip traefik + portainer
(management plane).

Also: STATUS.md note phone-side ntfy + email verified ✓ by user 2026-05-25.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 09:48:26 +03:00

7.1 KiB
Raw Blame History

books-vds-stacks-to-portainer

Migrate SSH-compose стеки на books VDS (89.253.255.133) в Portainer-managed через API. Pattern parallel [[.wiki/concepts/portainer-stack-management-vds]] (VDS-infra retro-migration 2026-05-22), но другой endpoint/Portainer URL/stack dirs.

Goal

Унифицировать ops surface на books VDS — все docker-compose стеки управляются через https://portainer.kzntsv.site (endpoint 1). Конец hybrid pain'у (Portainer для books-{api,web,scheduler,...} + SSH-compose для elasticsearch/mongo/minio/books-db/traefik/proxy-chain). CI deploy workflow (.gitea/workflows/deploy.yml в victor/books) только через Portainer API; SSH-compose vert не подключается; debug требует знать «is it Portainer or SSH compose» — больно.

Scope

Stack Current dir Adapt notes
books-db (MariaDB 10.6.4) /usr/docker/books-db/ bind ./data → absolutize. MYSQL_ROOT_PASSWORD env (передать через Portainer API env array).
mongo (shared) /usr/docker/mongo/ bind ./data/{db,configdb} → absolutize. MONGO_INITDB_ROOT_* env.
minio /usr/docker/minio/ bind ./data → absolutize. MINIO_ROOT_USER/PASSWORD env.
elasticsearch /usr/docker/elasticsearch/ bind ./data + ./snapshots (added 2026-05-25 для backup) → absolutize. path.repo env preserved.
proxy-chain /usr/docker/proxy-chain/ bind ./config → absolutize.

Skip (management plane):

  • traefik/usr/docker/traefik/ — recreate ломает access всему остальному.
  • portainer/usr/docker/portainer/ — self-managed; can't recreate себя.

Acceptance

  • 5 стеков (books-db, mongo, minio, elasticsearch, proxy-chain) появляются в GET /api/stacks под endpoint 1 (наряду с книгами books-{api,web,scheduler,ntfy,ops-mcp} + chrome).
  • Контейнеры работают, бинды смонтированы, data preserved (named volumes + binds через migration).
  • Smoke: каждый стек проходит health check соответствующий своему типу:
    • books-db: docker exec books-db mariadb -uroot -p... -e 'SELECT 1'1
    • mongo: docker exec mongo mongosh --eval 'db.adminCommand({ping:1})'ok:1
    • minio: HTTP https://elasticsearch.kzntsv.site (или внутренний minio endpoint) — 200 OK
    • elasticsearch: docker exec elasticsearch curl localhost:9200/_cluster/healthgreen|yellow
    • proxy-chain: smoke через тестового агента (TBD)
  • Backup pipeline (books-vds-backup-daily-kreknin) продолжает работать post-migration (compose dirs не используются runtime после migration, but /usr/docker/<svc>/data binds preserved — rsync paths остаются валидны).
  • Document в .wiki/concepts/portainer-stack-management-books-vds.md (или extend existing portainer-stack-management-vds.md с books VDS sections).

Decisions log

  • 2026-05-25: создана по запросу user'а после успешного books-vds-backup-daily-kreknin. Promised after backup pipeline live.
  • 2026-05-25: pattern reuse — .wiki/concepts/portainer-stack-management-vds.md migration script adaptable. Diff for books VDS: PORTAINER_URL, endpoint ID = 1, stack dirs /usr/docker/<svc>/ instead of /opt/stacks/<svc>/. PAT в pass под books-vds/full-env BOOKS_PORTAINER_API_KEY (may need fallback to JWT if 401).

Open questions

  • Endpoint 6 в books Portainer — stostayer VDS? Что мы за него отвечаем? Если да — после books-vds migration extend этой таски на stostayer. Если нет — отдельный вопрос, не блокер.
  • Volume preservation strategydocker compose down без -v preserves named volumes + binds. Verify для каждого стека что нет surprise named volumes которые могут эфемериться.
  • CI implications — деплой books-* stacks уже Portainer-managed. After migration of mongo/minio/etc — никаких изменений в CI не нужно (deploy.yml только books-api/web/scheduler, не infra). Confirm.
  • ES snapshot path.repo edit preservation — текущий /usr/docker/elasticsearch/docker-compose.yml имеет path.repo + snapshots bind (added 2026-05-25). Migration must preserve. Backup в docker-compose.yml.bak-pre-snapshots-2026-05-25 есть для reference.

Completed steps

  • (not started)

Plan (sketch)

Phase 0 — pre-flight:

  1. Read each stack's docker-compose.yml + .env (if exists).
  2. Document existing env vars + binds per stack.
  3. Backup current compose files (docker-compose.yml.bak-pre-portainer-migration-2026-MM-DD).

Phase 1 — Portainer API setup:

  1. Verify PAT works (curl ... /api/stacks). If 401 → fallback to JWT via admin password (from pass show books-vds/full-env BOOKS_VDS_ROOT_PASS adapted to Portainer admin — may differ).
  2. Build adapter script scripts/books-vds-portainer-migrate.sh (clone-and-adapt of VDS-infra version, see .wiki/concepts/portainer-stack-management-vds § Migration script).

Phase 2 — per-stack migrate (one at a time, verify between):

  1. proxy-chain (lowest blast radius)
  2. minio (read-mostly, books-api retries OK)
  3. mongo (shared) — books-api + books-task-runner retry-tolerant? VERIFY first
  4. books-db (MariaDB) — books-api uses connection-pool, brief downtime survivable
  5. elasticsearch — currently unused (per user), zero impact

Phase 3 — wiki + close:

  1. Document в .wiki/concepts/portainer-stack-management-books-vds.md (or extend existing).
  2. Update .wiki/entities/books-vds.md — flip каждый стек в SSH-managed → Portainer-managed table.
  3. Update STATUS.md → 🟢.

Notes

  • books-job-scheduler-mongo уже Portainer-managed (часть books-job-scheduler stack). Не в scope этой таски.
  • books-docker-proxy + books-docker-proxy-ro — часть books-ops-mcp stack (Portainer). Not in scope.
  • Buildx builders (buildx_buildkit_builder-*) — transient containers без compose, игнорируем.
  • Backup pipeline depend — после migration paths /usr/docker/<svc>/data остаются как bind sources, поэтому books-vds-backup-daily-kreknin/run.sh не требует изменений. Compose files (/usr/docker/<svc>/docker-compose.yml) станут reference only после migration.

Cross-refs