docs(#21): runbook dev-стенда — быстрый старт, таблица AC, зависимости и откат
Refs #21 Refs #15
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# dev/staging стенд awg-dash — runbook
|
||||
|
||||
Задача **#21** (эпик **#15**). Стенд для локальной разработки и проверки
|
||||
acceptance criteria до появления staging-окружения.
|
||||
|
||||
* Docker-хост: **192.168.1.147** (`ssh root@192.168.1.147`), Docker 29.4.x + compose v5.
|
||||
* Каталог состояния: **`/opt/awg-dash-dev/{config,data}`** (bind mount → `/config`, `/data`).
|
||||
* Compose project: **`awg-dash-dev`** (изолирован от PoC-контейнеров `amneziawg-client`).
|
||||
* Хост-порт приложения: **8180** (`AWG_DASH_PORT`), внутри контейнера — **8080**.
|
||||
Порт 8080 на dev-хосте занят другим сервисом (drawio), поэтому проброс нестандартный.
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
```bash
|
||||
# на Docker-хосте, из корня репозитория
|
||||
export AWG_DASH_HOST_DIR=/opt/awg-dash-dev
|
||||
make dev-up # docker compose up -d --build (проект awg-dash-dev)
|
||||
make dev-verify # проверка AC: health 200 + состояние переживает restart
|
||||
curl -fsS http://127.0.0.1:8180/api/v1/health
|
||||
make dev-logs # логи контейнера
|
||||
make dev-down # остановить (каталоги состояния сохраняются)
|
||||
```
|
||||
|
||||
До реализации FastAPI-каркаса (**#31**) `/api/v1/health` не отвечает — контейнер
|
||||
работает как агент и помечается `unhealthy`. Чтобы проверить плумбинг стенда
|
||||
(порт, healthcheck, тома, restart) **до** #31, используйте health-заглушку:
|
||||
|
||||
```bash
|
||||
make dev-up-stub # + deploy/docker-compose.stub.yml (DEV-ONLY, api_stub.py)
|
||||
make dev-verify-stub # AC-1 проходит на заглушке, в отчёте api=stub
|
||||
```
|
||||
|
||||
Заглушка отвечает `{"status":"ok","stub":true,...}` только на `/api/v1/health` и
|
||||
никогда не должна использоваться в staging/prod.
|
||||
|
||||
## Проверка AC (#21)
|
||||
|
||||
| AC | Команда | Ожидание |
|
||||
|---|---|---|
|
||||
| AC-1: health 200 | `curl -fsS -o /dev/null -w '%{http_code}' http://127.0.0.1:8180/api/v1/health` | `200` (после мержа #31; до него — заглушка через `dev-verify-stub`) |
|
||||
| AC-2: состояние переживает restart | `make dev-verify` | маркеры в `/config` и `/data` совпадают до и после `docker compose restart` и `--force-recreate` |
|
||||
| AC-3: netns + мок-endpoint | `make test-netns` | 8/8 тестов, netns `awgt21-{client,gw,uplink}` создаются и сносятся |
|
||||
|
||||
`deploy/verify-dev-stand.sh` (за `make dev-verify`) печатает отчёт и возвращает:
|
||||
|
||||
| Код | Значение |
|
||||
|---|---|
|
||||
| 0 | AC-1 и AC-2 выполнены |
|
||||
| 1 | регрессия стенда (health не 200 с заглушкой, состояние не сохранилось) |
|
||||
| 2 | AC-1 заблокирован: API (#31) ещё не реализован, стенд при этом поднят |
|
||||
| 3 | заблокировано окружением: нет docker/compose или compose-файлов |
|
||||
|
||||
## Состав стенда
|
||||
|
||||
| Файл | Назначение |
|
||||
|---|---|
|
||||
| `docker-compose.dev.yml` | приложение: порт 8080 (наружу `${AWG_DASH_PORT:-8180}`), bind mount `/config` `/data`, healthcheck, NET_ADMIN/NET_RAW/SYS_MODULE, `/dev/net/tun` |
|
||||
| `docker-compose.stub.yml` | DEV-ONLY оверрайд: health-заглушка до #31 (`api_stub.py`) |
|
||||
| `docker-compose.test.yml` | тестовый стенд: привилегированный `netns`-раннер + `app` для API-тестов |
|
||||
| `api_stub.py` | минимальный HTTP-сервер `/api/v1/health` (только dev) |
|
||||
| `verify-dev-stand.sh` | проверка AC на Docker-хосте + JSON-отчёт |
|
||||
| `../tests/netns/` | netns-харнесс: топология client/gw/uplink + мок WireGuard-endpoint |
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
| Переменная | По умолчанию | Назначение |
|
||||
|---|---|---|
|
||||
| `AWG_DASH_PORT` | `8180` | хост-порт приложения |
|
||||
| `AWG_DASH_HOST_DIR` | `/opt/awg-dash-dev` | каталог состояния на хосте |
|
||||
| `AWG_DASH_IMAGE` | `awg-dash:dev` | имя образа (build или pull) |
|
||||
| `AWG_DASH_DOCKERFILE` | `deploy/Dockerfile` | путь к Dockerfile для build |
|
||||
| `COMPOSE_PROJECT_NAME` | `awg-dash-dev` | изоляция от других стендов |
|
||||
| `AWG_LOG_LEVEL` | `info` | уровень логирования приложения |
|
||||
|
||||
## Зависимости
|
||||
|
||||
| Зависимость | Состояние | Влияние на стенд |
|
||||
|---|---|---|
|
||||
| #16 (каркас репо, Makefile) | PR #47 | нужен `Makefile`, `requirements.txt`, `deploy/` |
|
||||
| #18 (образ, entrypoint) | PR #49 | нужен `deploy/Dockerfile` для `--build` |
|
||||
| #31 (каркас FastAPI, `/api/v1/health`) | Sprint 2 | без него AC-1 выполняется только с заглушкой |
|
||||
| #17 (CI-пайплайн) | Sprint 0 | `make test-netns-ci`, `make test-manifests` — готовые гейты для пайплайна |
|
||||
|
||||
## Откат и уборка
|
||||
|
||||
```bash
|
||||
make dev-down # остановить контейнеры проекта awg-dash-dev
|
||||
make dev-reset # down --remove-orphans (состояние сохраняется)
|
||||
docker image rm awg-dash:dev # откатить образ (пересобрать из предыдущего коммита)
|
||||
du -sh /opt/awg-dash-dev # состояние стенда
|
||||
```
|
||||
|
||||
Перед откатом образа проверьте проект: `docker compose -p awg-dash-dev ls`.
|
||||
Состояние (`/opt/awg-dash-dev`) не удаляется автоматически — это осознанно: там
|
||||
конфиги туннеля (`/config/awg0.conf`). Удаляйте вручную и только после бэкапа.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
* **Порт 8080 занят** на dev-хосте — наружу публикуется 8180. Меняйте `AWG_DASH_PORT`.
|
||||
* **`/dev/net/tun` обязателен**: без него entrypoint падает (`fail '/dev/net/tun не проброшен'`).
|
||||
* **Права на каталоги состояния**: entrypoint делает `chown awg:awg /config /data`;
|
||||
каталоги создаются на хосте от root — не меняйте владельца на хосте вручную.
|
||||
* **`docker compose restart` сохраняет тома**; `down -v` — нет. Никогда не используйте
|
||||
`down -v` на этом стенде: это удалит `/config` и `/data`.
|
||||
* **Заглушка `api_stub.py`** — только dev: она отвечает 200 на `/api/v1/health` и
|
||||
маскирует отсутствие API. Не включайте `docker-compose.stub.yml` в staging.
|
||||
* **netns-стенд вне Docker** требует root: `make test-netns` вернёт код 3, если нет
|
||||
CAP_NET_ADMIN/CAP_SYS_ADMIN (например, в непривилегированном CI-раннере).
|
||||
Reference in New Issue
Block a user