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

58 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-deploy``vds-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.
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-22 / handoff: board-viewer/.tasks/board-viewer-cron-deploy.md -->