5.5 KiB
IoT на Nubes — чек-лист деплоя (актуально на 2026-10-11)
Детальная процедура —
deployment-nubes-production.md. Здесь — конкретные шаги текущего стенда. Секреты НЕ хранятся в репо (*.keyв.gitignore); значения<>берутся изpg.key/deck/генератора.
0. Готово
- Образы в Gitea (
gitea.services.ngcloud.ru/nail):iot-service:v0.1.13(+ latest)iot-emqx:v0.2.5(+ latest),iot-service:v0.1.13(+ latest)
⚠️ Образ обязан иметь РОВНО ОДИН EXPOSE — платформа Nubes отказывает в создании
контейнера с «Не указан applicationUsePort…», если EXPOSE несколько. У emqx/emqx:5.5.1
их 7 → образ собирается через FROM scratch + COPY --from=base / / (EXPOSE не
наследуется), остаётся только 8083. Параметра applicationUsePort у провайдера nubes
3.1.0 нет — обойти на стороне Terraform нельзя, только пересборкой образа.
- shared-SQS тенант
demo-service(SSAK-b8fb2b3000c178b865091686, регионus-east-1):- очередь
iot-telemetry— создана; - DLQ
iot-telemetry-dlq— создана. - публичный endpoint:
https://sqs.sinefo.ru.
- очередь
- PostgreSQL managed: хост
postgresqlk8s-master.509145c3-ba71-4687-a084-d9dcbc88d3d2.svc.cluster.local:5432(изpg.key). ✅ создано через Nubes API (test): пользовательiotservice(roleddl_user→ CREATEDB+CREATEROLE), БДiotdb(owneriotservice). Парольiotservice— в vault инстанса.
1. PostgreSQL — ✅ ГОТОВО
Пользователь iotservice (role ddl_user, права CREATEDB+CREATEROLE) и БД iotdb (owner iotservice)
созданы через Nubes API (test): операции create_user (svcOperationId 241) и create_database (245)
на инстансе 509145c3-…. ⚠ Гранулярность: имя PG-пользователя подчиняется платформенному regex
^[A-Za-z0-9]+$ → iot_service НЕЛЬЗЯ (только iotservice).
Пароль: GET /instances/509145c3-…/vault/users (Nubes API, test) → поле iotservice.password.
Подключение:
IOT_PG_DSN = postgresql://iotservice:<PG_PASS>@postgresqlk8s-master.509145c3-ba71-4687-a084-d9dcbc88d3d2.svc.cluster.local:5432/iotdb?sslmode=require
Таблицы (iot_devices, per-tenant БД телеметрии) создаются кодом при старте.
2. EMQX-контейнер (создаётся ПЕРВЫМ, CPU ≥ 1000m)
Образ: gitea.services.ngcloud.ru/nail/iot-emqx:v0.2.5, порт из EXPOSE = 8083.
Env (все — при создании, потом не меняются):
| Переменная | Значение |
|---|---|
EMQX_AUTHENTICATION__1__SERVER |
postgresqlk8s-master.509145c3-ba71-4687-a084-d9dcbc88d3d2.svc.cluster.local:5432 |
EMQX_AUTHENTICATION__1__DATABASE |
iotdb |
EMQX_AUTHENTICATION__1__USERNAME |
iotservice |
EMQX_AUTHENTICATION__1__PASSWORD |
<PG_PASS> |
EMQX_AUTHORIZATION__SOURCES__1__SERVER |
как AUTHENTICATION |
EMQX_AUTHORIZATION__SOURCES__1__DATABASE |
iotdb |
EMQX_AUTHORIZATION__SOURCES__1__USERNAME |
iotservice |
EMQX_AUTHORIZATION__SOURCES__1__PASSWORD |
<PG_PASS> |
EMQX_LOG__CONSOLE_HANDLER__LEVEL |
warning |
⚠ Не задавать ...__URL (HTTP-auth старой схемы — уронит под). SSL обязателен.
После создания — записать UUID namespace EMQX (нужен в MQTT_HOST).
3. iot-service-контейнер (создаётся ВТОРЫМ)
Образ: gitea.services.ngcloud.ru/nail/iot-service:v0.1.13, порт из EXPOSE = 9090.
Env (обязательные — секреты; необязательные имеют дефолты в образе):
| Переменная | Значение |
|---|---|
IOT_PG_DSN |
postgresql://iotservice:<PG_PASS>@postgresqlk8s-master.509145c3-ba71-4687-a084-d9dcbc88d3d2.svc.cluster.local:5432/iotdb?sslmode=require |
SQS_ACCESS_KEY |
SSAK-b8fb2b3000c178b865091686 |
SQS_SECRET_KEY |
<из Admin API / лога сервиса> |
MQTT_USERNAME |
iot-bridge (device_id строки бриджа) |
MQTT_PASSWORD |
<сгенерировать> |
JWT_HMAC_SECRET |
<сгенерировать> |
SQS_ENDPOINT |
https://sqs.sinefo.ru (не дефолт: shared-sqs НЕ в кластере, а на ВМ 213) |
SQS_QUEUE_NAME |
iot-telemetry (дефолт) |
SQS_DLQ_NAME |
iot-telemetry-dlq (дефолт) |
MQTT_HOST |
<UUID namespace EMQX из шага 2> |
MQTT_PORT |
8083 (дефолт) |
AUTH_TEST_MODE |
false |
При старте монолит: подключается к PG, создаёт схему, EnsureBridgeDevice(MQTT_USERNAME, MQTT_PASSWORD) → строка __bridge/iot-bridge в iot_devices для EMQX-auth.
4. Проверка
/healthи/ready(порт 9090) → 200.- В логе:
bridge: MQTT connected,bridge: subscribed,consumer: SQS queue resolved. - EMQX:
curl https://<emqx-домен>/mqtt→ 400 (норма). wss-рука — клиент с subprotocolmqtt.