Files
admin/.wiki/concepts/books-vds-no-gitea-actions.md

41 lines
5.2 KiB
Markdown
Raw 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.
---
title: books-vds Gitea Actions выпилены — сборка только локально (решение vitya 2026-08-23)
status: live
tags: [books-vds, ci, gitea-actions, build, decision]
---
# Gitea Actions на books-vds — выпилены полностью (директива vitya 2026-08-23)
**Решение юзера:** никакого Gitea Actions / CI-раннера. Сборка образов — **только локально на рабочей машине**, деплой — прямыми `PUT /api/stacks/<id>` в Portainer.
## Что выпилено
- Workflow-файлы удалены и запушены: `books/.gitea/workflows/{build,deploy,build-tools,build-sched-daemon}.yml`, `vds-ops-mcp/.gitea/workflows/build.yml` (там был РЕАЛЬНЫЙ автобилд `on: push` — «автосборка», которую юзер увидел).
- books-vds (`89.253.255.133`): раннер вычищен под ноль:
- `systemctl stop/disable gitea-runner.service` + `rm /etc/systemd/system/gitea-runner.service`
- `rm -rf /opt/gitea-runner` (бинарник, config.yaml, .runner)
- `docker rm -f GITEA-ACTIONS-TASK-*` (job-контейнеры)
- `userdel -r gitea-runner`
- vds-kzntsv: следов не было (проверено).
## Процедура локальной сборки + публикации (проверена 2026-08-23)
1. `git archive <sha> | tar -x -C /c/tmp/build` (чистый контекст, без node_modules/.git)
2. `VERDACCIO_TOKEN=<jwt> docker build --secret id=verdaccio_token,env=VERDACCIO_TOKEN -f packages/<svc>/Dockerfile -t <svc>:<sha> .`
3. `docker save` → tar. **Docker 29 на этой машине сразу отдаёт OCI-layout** (`oci-layout` + `index.json` + `blobs/sha256/*`) — конвертация не нужна, `--format oci` отсутствует и не требуется. `index.json` → OCI **index** (multi-arch: amd64 child + attestation `platform: unknown/unknown`). Дочерний **amd64-манифест** лежит в `blobs/sha256/<index-digest>` (прочитать index-блоб, взять `manifests[]` с `platform.architecture == 'amd64'`).
4. Заливка блобов curl'ом: HEAD-check → если нет — `POST /v2/<repo>/blobs/uploads/` → `PUT <Location>&digest=sha256:<d>` с телом (монолитный, Content-Length). Большой слой: `cat blob | curl -X PATCH -T -` (chunked) + финальный `PUT &digest` (Location брать из PATCH-ответа). Перед большим чтением файла — `sync; echo 3 > /proc/sys/vm/drop_caches` (books-vds 3.9GB RAM → OOM на 2GB файле).
5. Манифест: если `index.json` → OCI index (multi-arch, у Docker Desktop так) — **класть дочерний amd64-манифест** (`application/vnd.oci.image.manifest.v1+json`), не индекс (реестр: MANIFEST_INVALID).
6. Креды реестра: `docker login registry.kzntsv.site -u books-ci --password-stdin` (актуальный пароль books-ci — в `/opt/books/sched/docker-config.json` на books-vds; в `/root/.docker/config.json` был УСТАРЕВШИЙ → 401 на push).
## Gotcha: большие пуши через traefik умирают
`docker buildx --push` 1.5-2GB слоёв через `registry.kzntsv.site` (traefik buffering middleware `maxRequestBodyBytes=4GB`) → `Client Closed Request`: traefik буферизует тело в RAM vds-kzntsv (1GB free) + чтение с buildkit-кэша медленное + OOM. curl монолитными PUT/PATCH работает (54MB/s). Связано: [[registry-traefik-buffering-gotcha]].
## Деплой: Portainer PUT gotchas (2026-08-23, деплой master-a448cad)
**`PUT /api/stacks/<id>?endpointId=1` — синхронный и тянет образ ВНУТРИ запроса** (676МБ с registry через интернет = минуты). Клиентский таймаут (90с urllib) рвёт ожидание, но операция НЕ отменяется — Portainer доделывает server-side (файл стека обновляется, pull идёт, контейнер пересоздаётся). Правильный флоу: `PUT` с timeout 900+, при обрыве — НЕ пере-PUT (задвоит деплой), а проверить контейнеры:
```
GET /api/endpoints/1/docker/containers/json?all=1 # фильтр по Names: books-web / bookva-web → Image + Status
GET /api/endpoints/1/docker/images/json # образ уже на VDS? (показывает in-flight pull)
```
Смоук/верификация: `DELETE /api/fbs/pickingLists/:id` → `{taskId}`, статус `GET /api/fbs/tasks/<uuid>`, run в sched daemon: `docker exec books-sched node -e 'fetch("http://localhost:3031/api/runs?task=<name>&limit=3",{headers:{"Authorization":"Bearer <SCHED_ADMIN_KEY>"}})...'` (**curl в контейнере нет**, node fetch есть; ключ — из env стека). Nuxt-прокси `/admin/scheduler/**` для внешних проверок бесполезен: гейтится `requireAdmin` (JWT isAdmin), `?token=` API-ключ → 403.