diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 20205d7..dbacb48 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -10,6 +10,16 @@ _Updated: 2026-05-22 (Сессия завершена. MSSQL Express 2022 live 🔵 Blocked — waiting on external input --> +## ⚪ [board-viewer-vds-deploy] — поднять `board.kzntsv.site` (docker-compose stack за traefik basic-auth) + +**Status:** ready +**Where I stopped:** (not started — handoff из dev-проекта `~/projects/board-viewer/`, артефакты `deploy/` code-complete + smoke-verified) +**Next action:** DNS A-record `board.kzntsv.site` → VDS IP; затем `docker build -f deploy/Dockerfile.build -t registry.kzntsv.site/board-viewer-build:latest . && docker push …` на dev-машине; затем bootstrap `/opt/stacks/board-viewer/` на VDS — см. полный чек-лист в `board-viewer-vds-deploy.md` (Pending ops actions) и `~/projects/board-viewer/deploy/README.md`. +**Branch:** n/a + + +--- + ## 🟢 [owncloud-vds-deploy] — oCIS 7.1.0 на vds-kzntsv live, 25 044 объектов / 26 GB **Closed:** 2026-05-22 — import complete. 99.97% (22.2 GB / 25 038 objs) залито rclone'ом за ~2.5 ч (3.35 MiB/s uplink). Оставшиеся 6 файлов (4.04 GB) — 4× .pat ~221 MB + 2× .seospider 1.55+1.7 GB — упали с 502 (later 500) на каждой попытке rclone из-за 60-секундного timeout где-то в HTTP stack (Go http.Client.Timeout в reva v2.27 datagateway, **не** traefik). Workaround: throwaway sftp-only ssh-key → агент scp'ит в `/tmp/oc-import/` на VDS → c VDS curl PUT loopback'ом через traefik в правильные oCIS пути (local network 142 MB/s — все 6 файлов залиты за 28 секунд total). Все PROPFIND size match. Throwaway-key revoked, staging cleaned. diff --git a/.tasks/board-viewer-vds-deploy.md b/.tasks/board-viewer-vds-deploy.md new file mode 100644 index 0000000..8e920ed --- /dev/null +++ b/.tasks/board-viewer-vds-deploy.md @@ -0,0 +1,57 @@ +# 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. + +