Files
admin/.tasks/board-viewer-vds-deploy.md
vitya 65c6ad9eea tasks: import board-viewer-vds-deploy from dev-project [board-viewer-vds-deploy]
Ops-handoff из ~/projects/board-viewer/.tasks/[board-viewer-cron-deploy]:
dev-проект сдал code-complete (артефакты deploy/ + smoke против real Gitea),
оставшиеся pending — DNS / build+push / VDS bootstrap / smoke — это ops-сторона.

Per новое правило workshop CLAUDE.md §5 — таски с ops acceptance criteria
(DNS, docker stack, traefik, systemd, etc.) живут в .admin, не в app-проекте.
2026-05-22 16:05:50 +03:00

4.1 KiB
Raw Permalink Blame History

board-viewer-vds-deploy

Goal

Поднять статическую HTML-доску board-viewer (read-only kanban over Gitea API) на VDS под board.kzntsv.site. Двухсервисный docker-compose stack (cron-loop build + nginx serve) за traefik с basic-auth. Periodic regen каждые ~5 мин внутри build-контейнера.

Артефакты deploy/ написаны и валидированы в dev-проекте ~/projects/board-viewer/deploy/. Эта таска — чисто ops-handoff: DNS, image build/push, bootstrap stack, smoke.

Source dev-project

  • Repo: ~/projects/board-viewer/https://git.kzntsv.site/OpeItcLoc03/board-viewer.git
  • Artefacts (HEAD-of-master, code-complete):
    • deploy/docker-compose.yml — стек на proxy network, traefik labels
    • deploy/Dockerfile.build — node:22-alpine + cron-loop entrypoint
    • deploy/nginx.conf — static serving + Cache-Control
    • deploy/auth.toml.example — шаблон Gitea token + repo whitelist
    • deploy/.env.example — шаблон BOARD_VIEWER_USERS (basic-auth bcrypt, с $$-escape)
    • deploy/README.md — полный One-time setup + Day-to-day + DR
  • Compose syntax валидирован (docker compose config)
  • Smoke против real Gitea (78 records, 4 repos) — node --experimental-strip-types src/cli.ts производит dist/index.html + dist/static/

Pending ops actions

  • DNS: A-record board.kzntsv.site → VDS IP (где живёт DNS — Cloudflare / namecheap)
  • Build & push image: на dev-машине из корня репо: docker build -f deploy/Dockerfile.build -t registry.kzntsv.site/board-viewer-build:latest . docker push registry.kzntsv.site/board-viewer-build:latest
  • Bootstrap /opt/stacks/board-viewer/ на VDS:
    • скопировать docker-compose.yml + nginx.conf из репо
    • cp auth.toml.example auth.toml, вписать реальный Gitea token + board_viewer_repos list
    • cp .env.example .env, сгенерировать htpasswd -nbB viewer 'PASS', escape каждый $$$, вписать в BOARD_VIEWER_USERS
    • chmod 600 auth.toml .env
  • sudo docker compose pull && sudo docker compose up -d
  • Smoke:
    • curl -I https://board.kzntsv.site/ → 401
    • curl -I -u viewer:'PASS' https://board.kzntsv.site/ → 200
    • sudo docker compose logs --tail=200 build → видна строка wrote /output/index.html (N records from M repos)

Acceptance criteria

  • DNS board.kzntsv.site резолвится в VDS IP
  • Traefik route на board.kzntsv.site с basic-auth middleware (creds из .env)
  • Build-контейнер крутится без рестартов, каждые BOARD_TICK_SEC (default 300s) обновляет /output/index.html
  • Web-контейнер раздаёт dist/ через nginx; 401 без креды, 200 с
  • В password manager сохранены: viewer password + Gitea token (на случай DR)

Decisions log

  • 2026-05-22: ownership transferred from ~/projects/board-viewer/.tasks/[board-viewer-cron-deploy] (dev-проект, code-complete) на .admin/.tasks/ per новое правило workshop CLAUDE.md §5 (domain-промоушены с ops-acceptance → target=.admin). Slug изменён cron-deployvds-deploy для cross-project ясности.

Notes

  • Mechanism — docker-compose stack (не systemd timer); гомогенно с existing VDS pattern (Gitea, registry, ntfy). Cron-loop = while true; do node cli.ts; sleep ${BOARD_TICK_SEC}; done внутри build-контейнера.
  • Rate-limit: 4 repos × ~2 Gitea API calls каждые 5 мин = ~24-100 calls/period, токенизированный Gitea не упрётся.
  • DR-сценарий — см. deploy/README.md секция «Disaster recovery». No persistent state — каждый render fresh из Gitea.