fix(emqx): образ с одним EXPOSE (scratch) + конфиг без salt_rounds — платформа требует ровно один порт
This commit is contained in:
@@ -52,3 +52,42 @@
|
|||||||
|
|
||||||
- `go build ./...`, `go vet ./...`, `go test -race ./...` — зелёные.
|
- `go build ./...`, `go vet ./...`, `go test -race ./...` — зелёные.
|
||||||
- Push: `54fe1f5..f41a9fe` в `origin/master`.
|
- Push: `54fe1f5..f41a9fe` в `origin/master`.
|
||||||
|
|
||||||
|
## 5. Деплой на Nubes (Terraform) — образ EMQX, 2026-10-11
|
||||||
|
|
||||||
|
`terraform apply` упал на `nubes_http.iot_emqx` через ~70 с (стадия validation,
|
||||||
|
22.0 с): платформа требует РОВНО ОДИН `EXPOSE` в образе, иначе
|
||||||
|
«Не указан applicationUsePort…». У `emqx/emqx:5.5.1` — 7 EXPOSE
|
||||||
|
(18083/1883/4370/5369/8083/8084/8883). Параметра `applicationUsePort` у
|
||||||
|
провайдера nubes 3.1.0 нет (проверено: `generated/prod/resources_yaml/98_http.yaml`
|
||||||
|
+ `generated/prod/docs-rendered/http.md` + исходники провайдера — совпадений нет),
|
||||||
|
поэтому лечится только пересборкой образа.
|
||||||
|
|
||||||
|
Что сделано (образ `nail/iot-emqx:v0.2.5`):
|
||||||
|
|
||||||
|
1. `emqx/Dockerfile` — multi-stage: `FROM emqx/emqx:5.5.1 AS base` →
|
||||||
|
`FROM scratch` → `COPY --from=base / /`. EXPOSE/ENV/VOLUME наследуемого образа
|
||||||
|
НЕ переносятся в `scratch`, поэтому остаётся единственный `EXPOSE 8083`.
|
||||||
|
ENV `LANG`/`LC_ALL`/`PATH` объявлены заново. `USER emqx` + `WORKDIR /opt/emqx`
|
||||||
|
+ штатные `ENTRYPOINT`/`CMD` базы.
|
||||||
|
- ⛔ Попытка `FROM debian:bookworm-slim` + `COPY --from=base / /` НЕ работает:
|
||||||
|
`cannot copy to non-directory: /bin` — в bookworm `/bin` симлинк (usrmerge),
|
||||||
|
в emqx-образе (Debian 11) `/bin` — реальный каталог.
|
||||||
|
2. `emqx/emqx.conf` — удалён `salt_rounds = 10` из `password_hash_algorithm`:
|
||||||
|
схема 5.5.1 его НЕ принимает (`unknown_fields, unknown => "salt_rounds"` →
|
||||||
|
`call_hocon_failed`, контейнер не стартует). Роль поля нулевая: EMQX только
|
||||||
|
сверяет bcrypt-хеш из БД, cost берётся из самого хеша.
|
||||||
|
|
||||||
|
Верификация образа (локально):
|
||||||
|
- `docker inspect … --format '{{json .Config.ExposedPorts}}'` → `{"8083/tcp":{}}`;
|
||||||
|
- запуск контейнера → `Listener tcp:default on 0.0.0.0:1883 started`,
|
||||||
|
`Listener ws:default on 0.0.0.0:8083 started`, `EMQX 5.5.1 is running now!`,
|
||||||
|
статус `running`. Ошибки `econnrefused` к `127.0.0.1:5432` в тесте ожидаемы
|
||||||
|
(PG рядом нет).
|
||||||
|
- Реестр Gitea: теги `latest`, `v0.2.4`, `v0.2.5`.
|
||||||
|
- `terraform.tfvars` / `terraform.tfvars.example`: `iot_emqx_version = "v0.2.5"`.
|
||||||
|
|
||||||
|
⚠️ Блокер деплоя: инстанс `iot-emqx` (`3bdaef8e-e880-4419-870a-bd0158826751`)
|
||||||
|
остался в состоянии `not created` после неудачного apply и держит имя. По
|
||||||
|
документации платформы такие инстансы через API не удаляются — удалять вручную
|
||||||
|
в ЛК (deck). `terraform state list` пуст (в state ничего не записалось).
|
||||||
|
|||||||
+20
-6
@@ -1,14 +1,28 @@
|
|||||||
# EMQX для IoT на платформе Nubes.
|
# EMQX для IoT на платформе Nubes.
|
||||||
# Образ: gitea.services.ngcloud.ru/nail/iot-emqx (Gitea registry платформы).
|
# Образ: gitea.services.ngcloud.ru/nail/iot-emqx (Gitea registry платформы).
|
||||||
#
|
#
|
||||||
# БАЗА — официальный emqx/emqx:5.5.1 (проверен на платформе: заводится, логи в
|
# ⚠️ ВАЖНО: платформа Nubes требует РОВНО ОДИН EXPOSE у образа (иначе create падает
|
||||||
# stdout). Добавляем только наш emqx.conf (auth/ACL, listeners, логи).
|
# с «Не указан applicationUsePort, а expose в Dockerfile содержит несколько портов»).
|
||||||
# ⚠️ У образа 7 EXPOSE-портов (наследие базы) — deck-UI при СОЗДАНИИ требует
|
# База emqx/emqx:5.5.1 имеет 7 EXPOSE (18083/1883/4370/5369/8083/8084/8883), а EXPOSE
|
||||||
# один порт; в НАШЕМ кластере используется kubectl set image, вопрос одного
|
# не удаляется из наследуемого образа. Поэтому копируем rootfs базового образа в чистый
|
||||||
# EXPOSE для чужого кластера — отдельная задача (тикет Nubes).
|
# (EXPOSE НЕ переносится) и выставляем единственный порт 8083.
|
||||||
|
#
|
||||||
|
# БАЗА — официальный emqx/emqx:5.5.1. Добавляем только наш emqx.conf (auth/ACL, listeners, логи).
|
||||||
|
|
||||||
FROM emqx/emqx:5.5.1
|
FROM emqx/emqx:5.5.1 AS base
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
COPY --from=base / /
|
||||||
|
|
||||||
|
ENV LANG=C.UTF-8
|
||||||
|
ENV LC_ALL=C.UTF-8
|
||||||
|
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
|
||||||
COPY emqx.conf /opt/emqx/etc/emqx.conf
|
COPY emqx.conf /opt/emqx/etc/emqx.conf
|
||||||
|
|
||||||
EXPOSE 8083
|
EXPOSE 8083
|
||||||
|
|
||||||
|
USER emqx
|
||||||
|
WORKDIR /opt/emqx
|
||||||
|
ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"]
|
||||||
|
CMD ["/opt/emqx/bin/emqx", "foreground"]
|
||||||
|
|||||||
+5
-1
@@ -41,7 +41,11 @@ authentication = [
|
|||||||
}
|
}
|
||||||
password_hash_algorithm {
|
password_hash_algorithm {
|
||||||
name = bcrypt
|
name = bcrypt
|
||||||
salt_rounds = 10
|
## ⚠ salt_rounds НЕ поддерживается схемой 5.5.1 (проверено на образе
|
||||||
|
## emqx/emqx:5.5.1: «unknown_fields, unknown => "salt_rounds"» и
|
||||||
|
## call_hocon_failed). Оставлять его нельзя — контейнер не стартует.
|
||||||
|
## Роль поля нулевая: EMQX только СВЕРЯЕТ хеш из БД, а cost берётся из
|
||||||
|
## самого bcrypt-хеша, не из конфига.
|
||||||
}
|
}
|
||||||
query = "SELECT mqtt_password AS password_hash FROM iot_devices WHERE enabled = true AND (namespace || '_' || device_id = ${username} OR (namespace = '__bridge' AND ${username} = device_id)) LIMIT 1"
|
query = "SELECT mqtt_password AS password_hash FROM iot_devices WHERE enabled = true AND (namespace || '_' || device_id = ${username} OR (namespace = '__bridge' AND ${username} = device_id)) LIMIT 1"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user