Окружение разработки АРМ КА (docs/dev/)

Локальная инфраструктура workspace одной командой: PostgreSQL 16, NATS 2.10 без JetStream и MinIO с бакетом arm-ka.

Статус (фаза 1): в compose сейчас только инфраструктура (postgres, nats, minio, minio-init). Профиль services (контейнеры arm-core, tabular-parser, scan-gateway, scan-emulator) планируется — добавляется позже (задача 5.3), здесь не описан. До этого сервисы запускаются из venv против этой инфраструктуры (см. ниже).

Предварительные требования

  • Docker и compose v2 (проверено на docker 28 / compose 2.34).
  • uv и Python 3.11 — для запуска сервисов из venv (версия Python — как на платформе).
  • Свободные порты хоста (по умолчанию доступны только с 127.0.0.1, см. BIND_ADDR): 5432 (PostgreSQL), 4222 и 8222 (NATS и его мониторинг), 9000 и 9001 (MinIO API и консоль). Занятые порты меняются в .env (см. «Типичные проблемы»).

Запуск инфраструктуры

Команды — из каталога docs/dev/:

cp .env.example .env        # .env в git не попадает
docker compose up -d        # вернётся сразу; healthy — примерно через 6 с

Ожидание готовности (для скриптов и Makefile):

docker compose up -d && docker compose up -d --wait postgres nats minio

Голый docker compose up -d --wait возвращает код 1: одноразовый minio-init (создаёт бакет и завершается с кодом 0) compose 2.34 считает сбоем (container arm-ka-minio-init-1 exited (0)). Поэтому --wait нужно давать со списком долгоживущих сервисов — как выше.

Проверка:

docker compose ps                                            # postgres, nats, minio — Up (healthy); minio-init — Exited (0)
docker compose exec postgres sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "select version()"'
curl -s localhost:8222/healthz                               # {"status":"ok"}
curl -s localhost:8222/varz | grep -A1 jetstream             # "jetstream": {} — JetStream не включён
docker compose run --rm --entrypoint sh minio-init -c 'mc alias set local http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD" >/dev/null && mc ls local'
                                                             # [...]  0B arm-ka/

Консоль MinIO — http://localhost:9001 (по умолчанию minioadmin / minioadmin); S3 API — localhost:9000. Схема БД (dkb) создаётся миграциями arm-core, не compose.

Переменные .env

Файл читают docker compose (из этого каталога) и, вторым блоком, сервисы при запуске из venv. Значения по умолчанию — только для dev.

Блок compose:

Переменная По умолчанию Для чего
BIND_ADDR 127.0.0.1 адрес привязки всех портов хоста; 0.0.0.0 — доступ с других машин (небезопасно, см. «Примечания»)
POSTGRES_DB armka имя БД
POSTGRES_USER armka пользователь БД
POSTGRES_PASSWORD armka пароль БД
POSTGRES_PORT 5432 порт PostgreSQL на хосте
NATS_PORT 4222 клиентский порт NATS на хосте
NATS_MONITOR_PORT 8222 порт мониторинга NATS (/varz, /healthz)
MINIO_ROOT_USER minioadmin администратор MinIO
MINIO_ROOT_PASSWORD minioadmin пароль администратора MinIO
MINIO_API_PORT 9000 порт S3 API на хосте
MINIO_CONSOLE_PORT 9001 порт консоли MinIO на хосте
MINIO_BUCKET arm-ka единственный бакет, создаётся minio-init

Блок сервисов (запуск из venv против compose по localhost, формат шаблона команды):

Переменная По умолчанию Для чего
DEBUG true dev-режим: пакеты raisa_* импортируются условно
OPENBAO__DATABASE__DATABASE_URL postgresql+asyncpg://armka:armka@localhost:5432/armka подключение к PostgreSQL (asyncpg)
OPENBAO__MINIO__MINIO_URL localhost:9000 адрес MinIO без схемы (host:port, так ждёт miniopy-async)
OPENBAO__MINIO__MINIO_ADMIN_LOGIN minioadmin логин MinIO
OPENBAO__MINIO__MINIO_ADMIN_PASSWORD minioadmin пароль MinIO
OPENBAO__MINIO__MINIO_BUCKET arm-ka бакет
OPENBAO__NATS__NATS_URL nats://localhost:4222 адрес NATS
OPENBAO__NATS__NATS_SEED пусто nkey seed; пусто — подключение без nkeys
OPENBAO__NATS__NATS_JWT пусто JWT NATS; пусто — подключение без nkeys
OPENBAO__SMB__SMB_HOST localhost заглушка SMB (в Срезе 0 не используется); блок обязателен для Settings arm-core
OPENBAO__SMB__SMB_PATH share заглушка SMB
OPENBAO__SMB__SMB_LOGIN user заглушка SMB
OPENBAO__SMB__SMB_PASSWORD password заглушка SMB
NATS_ENABLED true включает подключение arm-core к NATS; без него /healthcheck показывает nats=off

Два блока описывают одни и те же ресурсы: при смене порта, пароля, пользователя или бакета меняйте обе части.

Сброс окружения

docker compose down        # останавливает контейнеры; тома postgres-data и minio-data сохраняются
docker compose down -v     # полный сброс: удаляет тома postgres-data и minio-data (БД и бакет — с нуля)

Имя проекта compose фиксировано (name: arm-ka), поэтому тома общие для любого worktree (.wt/<срез>/docs/dev): сброс из одного worktree затрагивает все.

Запуск сервисов из venv без Nexus (черновик)

Черновик: будет дописан и проверен вручную в задаче 5.4 (сквозная проверка). make venv и make test-integration в tabular-parser и scan-gateway будут доступны после задач этих сервисов; сейчас они есть в arm-core.

Пакеты raisa_* из Nexus банка вне банка недоступны (D-10). Поэтому make venv ставит requirements.txt без строк raisa_* (фильтр grep -v '^raisa_'), код импортирует raisa_* условно (при DEBUG=true), а npm-пакеты raisa-* в web/package.json вынесены в optionalDependencies.

Шаги для сервиса (пути — относительно каталога его репозитория; в workspace docs/ лежит рядом, ../docs/dev/):

# 1. поднять инфраструктуру (из docs/dev/, см. выше)
# 2. из корня репозитория сервиса:
cp ../docs/dev/.env.example api/.env
make venv                                  # api/.venv: Python 3.11 + зависимости без raisa_*
cd api && .venv/bin/python run_server.py   # сервис подключается к PostgreSQL/NATS/MinIO по localhost
# 3. в другом терминале:
curl -s localhost:<порт сервиса>/healthcheck

Порт сервиса задаётся его настройками; в профиле services по spec это 8000 (arm-core), 8001 (tabular-parser), 8002 (scan-gateway). Для arm-core в ответе /healthcheck ожидаются version и nats = ok — при NATS_ENABLED=true (задан в .env.example; без него nats = off). Для tabular-parser и scan-gateway ожидаемые поля и переменные зависят от их настроек — будет уточнено в задачах 5.x.

Интеграционные тесты сервисов против compose (черновик)

Черновик: уточняется после задач 3.x и 5.x.

Общий набор целей (up, test, test-integration, lint, check, check-full) есть во всех сервисных репозиториях (arm-core, tabular-parser, scan-gateway); семантика, состав check-full, порядок перед PR и пропуск тестов без docs/fixtures описаны в checks.md; эталон рецептов общих целей — Makefile.common. Кратко: make check — быстрые проверки без Docker, make check-full — check + интеграционные тесты против этого compose + образ (для arm-core ещё сверка с DBML, миграции и web); выполняется перед созданием PR.

Интеграционные тесты требуют поднятой инфраструктуры: сначала docker compose up -d && docker compose up -d --wait postgres nats minio, затем make test-integration (или make check-full) в репозитории сервиса. Для scan-gateway эмулятор ИС Сканирование поднимается в процессе интеграционного теста (отдельный контейнер появится вместе с профилем services). Общее описание проверок — checks.md.

Проверка контракта

Из корня репозитория docs: python scripts/validate_contracts.py — валидирует примеры в contracts/examples/ тремя схемами из contracts/ (3 схемы, 8 примеров; нужен jsonschema). Или make venv && make check (ещё openspec validate), см. checks.md.

Примечания

  • Образы MinIO неофициальные. Официальные minio/minio и minio/mc недоступны (Docker Hub — denied, на quay.io нет нужных тегов), поэтому в compose стоят alpine/minio:RELEASE.2025-10-15T17-29-55Z и bitnamilegacy/minio-client:2025.7.21, а сервис minio запущен с user: "0:0" (иначе образ не пишет в свежий том) — только для dev. Решения R-5/R-6: design.md, раздел «Decisions made without discussion», решения №16–17. Замена на официальные образы — две строки image: в docker-compose.yml (и удаление user: "0:0").
  • Безопасность. По умолчанию порты публикуются только на 127.0.0.1 (BIND_ADDR), снаружи машины они недоступны. Чтобы открыть их для других машин, задайте в .env BIND_ADDR=0.0.0.0 — но пароли по умолчанию (armka, minioadmin) годятся только для dev, поэтому сначала смените их (в обоих блоках .env) и не делайте этого в недоверенной сети.

Типичные проблемы

  • Порт занят (address already in use): измените *_PORT в .env и одновременно соответствующий порт в OPENBAO__* (DATABASE_URL, MINIO_URL, NATS_URL); перезапустите docker compose up -d.
  • minio-init завис или завершился с ошибкой: docker compose logs minio-init; чаще всего minio не стал healthy — docker compose logs minio. Повторный docker compose up -d идемпотентен.
  • Остаточные тома от прошлых запусков (старый пароль БД, бакет не тот): docker compose down -v и запуск заново.
  • up -d --wait возвращает код 1: см. раздел «Запуск инфраструктуры» — указывайте сервисы явно.