Перейти к основному содержимому

Развёртывание

Всё создаётся скриптами из каталога infra — вручную в веб-консоли Oracle ничего делать не нужно и не следует.

к сведению
Текущее состояние машин — в infra/README.md

Здесь оно намеренно не дублируется: это оперативная сводка, она меняется чаще документации, и вторая копия разъедется с первой молча. Что стоит знать из неё на входе — имён теперь четыре, сертификат один на все четыре и автопродление включено.

Как это устроено

Две машины Oracle Always Free, и разделение между ними — не вкусовое.

интернет
│ только 443 (80 → редирект, 22 → обслуживание)

Машина B — публичная, nginx + TLS, один адрес и четыре имени
panel.… → панель оператора (статика) + её /api/ → машина A
api.… → только /device/* → машина A, всё прочее 404
ota.… → манифест обновлений и /assets/
docs.… → эта документация (статика)
голый IP → соединение рвётся (444)

▼ приватная сеть, снаружи недостижима
Машина A — сервер: NestJS + SQLite, публичного адреса нет вовсе

У сервера нет публичного адреса: наружу он ходит только сам, входящих соединений из интернета к нему не существует. Это дешевле любой настройки файрвола и надёжнее.

Почему имён четыре, а не одно, и что именно это даёт — четыре имени. Коротко: в фильтр на роутере объекта попадают только api и ota, и панель оператора становится постамату недоступна вовсе.

Документация

Сайт собирается в статику. Node в проде не нужен: на сервере лежат файлы, отдаёт их nginx.

cd apps/docs
npm run build # → build/
npm run serve # локальная проверка того, что собралось
npm start # режим разработки с перезагрузкой

Выкладка — тем же скриптом, что и панель:

infra/scripts/deploy-static.sh --docs ../apps/docs/build

Он кладёт содержимое в /srv/postamat/docs на машине B, откуда его отдаёт отдельный блок server из infra/machine-b/postamat.nginx.conf — тот, что слушает имя docs.1.router.thepragmaticdev.support.

осторожно
baseUrl — это /, и обратно на /docs/ его менять нельзя

Документация переехала на собственное имя и живёт в его корне, поэтому в docusaurus.config.ts задан baseUrl: '/'. Пока она стояла подкаталогом на общем хосте с панелью, здесь было '/docs/' — и это было обязательно.

Ошибка тихая в обе стороны: страницы открываются, просто ссылки на стили и скрипты уезжают не туда, и сайт выглядит сломанным. Кода возврата 404 при этом не будет, поэтому проверять надо глазами — открыть собранный сайт и посмотреть, есть ли оформление.

Смена схемы адресов — это всегда две правки сразу: baseUrl здесь и блок server в конфигурации nginx. По отдельности любая из двух ломает сайт.

url в конфигурации — https://docs.1.router.thepragmaticdev.support. Он влияет на абсолютные ссылки в собранной статике, поэтому при переезде правится вместе с остальным.

Про установку зависимостей

Обычный npm install из корня монорепо ставит и зависимости документации — это рабочий путь. Но он же тянет весь остальной репозиторий, включая тяжёлый мобильный проект, и падает целиком, если у соседнего пакета сломан package.json.

Поэтому у apps/docs есть собственные node_modules и собственный package-lock.json, поставленные так:

cd apps/docs && npm install --workspaces=false

Флаг говорит npm «поставь зависимости только этого каталога». Сборка документации после этого не зависит от состояния остального монорепо — полезно и на сервере сборки.

Панель оператора

Next.js со строго статической сборкой: npm run build --workspace=apps/panel кладёт в out/ одиннадцать страниц. Выкладка — deploy-static.sh --panel ../apps/panel/out.

Адрес сервера задаётся при сборке (NEXT_PUBLIC_API_BASE, по умолчанию /api) — то есть переезд API означает пересборку панели, а не правку конфига на сервере. Значение по умолчанию не случайно относительное: панель держит свой /api/ на своём же имени, поэтому браузер оператора остаётся в пределах одного источника и CORS не нужен вовсе.

Почему статика, а не Node: на машине B один гигабайт памяти, там уже живут nginx и сервер API, и второй Node-процесс держать нечем.

Сервер

apps/api — NestJS и SQLite, машина A. 🟡 Пишется прямо сейчас, поэтому здесь только то, что уже зафиксировано инфраструктурой:

  • выкладка — deploy-api.sh, с откатом при неуспехе;
  • сервис под systemd с ограничением памяти, своп 2 ГБ — машина маленькая;
  • резервная копия базы — backup.sh, учебное восстановление — restore-drill.sh (боевую базу не трогает);
  • постаматы ходят только до нашего backend — на роутере в проде стоит фильтр. Значит сервер обязан быть единственной точкой, откуда устройство получает и коды, и конфигурацию, и обновления. В фильтр при этом заносятся только имена api и otaпочему именно так.

Что мешает прямо сейчас

ЧтоПочему
тревоги не уходят наружу (письма, SMS)отправку делает сервер, он пишется

Эта строка важна не только разработчику: пока каналы не работают, ночная тревога будет замечена утром. Панель говорит это прямым текстом на своём экране тревог, и то же самое написано оператору.

Про имена, сертификат и состояние машин смотрите infra/README.md — там оперативная сводка, и она первична по отношению к этой странице.