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-проекте.
58 lines
4.1 KiB
Markdown
58 lines
4.1 KiB
Markdown
# 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 -->
|