PetroNet System¶
Платформын бусад баримт цөмийн зан төлөвийг тайлбарладаг. Энэ нэг нь өөр асуултад хариулна: энэ хост дээр юу хаана ажиллаж байна, ямар хаалга нээлттэй, юу нөөцлөгдөж байна.
Найман нэр, нэг хост¶
| Нэр | Юу | Ард нь |
|---|---|---|
petronet.mn |
Платформ — frontend ба /api/v1/* |
Next.js + Go |
admin.petronet.mn |
Операторын консол — /api/platform/v1/* |
Мөн тэр хоёр |
developer.petronet.mn |
Хөгжүүлэгчийн портал — OAuth клиент, scope, түлхүүр (цөмийн /dev) |
Мөн тэр хоёр, DEVELOPER_HOST |
monitoring.petronet.mn |
Grafana | Prometheus + хоёр exporter |
dwh.petronet.mn |
Дата агуулахын зураглал | Статик, өөрийн контейнер |
docs.petronet.mn |
Энэ баримт | Статик, MkDocs |
plan.petronet.mn |
Төслийн баримт — шаардлага, төлөвлөгөө, жишиг | Статик, MkDocs |
backups.petronet.mn |
Нөөцлөлтийн тайлбар | Статик, өөрийн контейнер |
Хоёр урсгал өөр origin дээр байгаа нь гоо зүйн биш: cookie нь hostname-аар хязгаарлагддаг тул тусдаа нэр нь тусдаа эрх гэсэн үг.
Хаягууд кодод биш, .env-ийн SERVICE_URL_*-д. Нүүр хуудас тохируулсныг нь л
карт болгож зурна — хаяггүй үйлчилгээ зурагдахгүй.
Төхөөрөмжийн шугамууд¶
Дээрх долоо нь ӨӨР ӨӨР үйлчилгээ. Доорх дөрөв нь тийм биш: яг ижил frontend
ба API, зөвхөн өөр origin дээр. Native клиент бүр өөрийн host-оор ханддаг тул
webview доторх дуудлага same-origin болж, session cookie нь SameSite=Strict
хэвээр ажиллаж, CORS preflight огт үүсэхгүй.
| Шугам | Аппын нэр | Клиент |
|---|---|---|
desktop.petronet.mn |
PetroNetDesktop |
macOS, Windows |
mobile.petronet.mn |
PetroNetMobile |
iOS/iPadOS, Android |
kiosk.petronet.mn |
PetroNetKiosk |
ЗАХИАЛГАТАЙ — клиент хараахан байхгүй |
pos.petronet.mn |
PetroNetPos |
ЗАХИАЛГАТАЙ — клиент хараахан байхгүй |
Хаяг нь хүн төхөөрөмжийг ХЭРХЭН БАРЬДГИЙГ нэрлэнэ, үйлдлийн системийг биш:
нэг ширээн дээрх Mac ба Windows хоёр нэг шугам. vhost нь
nginx/device-lines.petronet.mn.conf, эх сурвалж нь
native-apps/shared/device_lines.json.
Дөрвүүлэн 2026-09-05-нд асав. DNS дээр *.petronet.mn wildcard байсан тул
A бичлэг нэмэх алхам хэрэггүй байв; үлдсэнийг дарааллаар нь хийв:
nginx/device-lines.petronet.mn.conf→sites-available/,-enabled/certbot --nginx -d desktop.petronet.mn -d mobile.petronet.mn -d kiosk.petronet.mn -d pos.petronet.mn.env-ийнDEVICE_LINE_ORIGINS→ALLOWED_ORIGINS- ХАМГИЙН СҮҮЛД клиентийн доторх хаяг (
device_lines.json→client)
Дараалал нь ДҮРЭМ: эсрэгээр явбал апп байхгүй host руу чиглэж унана. Шинэ
шугам нэмэхэд ч мөн адил — DNS нь wildcard тул нэр өөрөө хүрч ирнэ, харин
nginx-ийн server_name-д бичих хүртэл 404 хариулна.
Портууд¶
Цөмийн анхдагч портуудыг энэ хост дээр урьд нь хөрш систем эзэлж байсан. Тэр систем 2026-09-03-нд алга болж, 3008/8082/5434 чөлөөтэй болсон ч энэ стек өөрийн портууд дээрээ үлдэнэ: ажиллаж буй суулгацын портыг солих нь compose, vhost, гэрчилгээ бүхнийг хөндөөд хариуд нь юу ч өгөхгүй. Энэ стекийнх:
| Порт | Юу |
|---|---|
| 5441 | postgres |
| 8099 | backend API |
| 3028 | бүрхүүл (Next.js) |
| 9093 | Prometheus |
| 3029 | Grafana |
| 9102 / 9189 | node / postgres exporter |
| 3030 / 3031 / 3032 / 3033 | dwh / docs / backups / plan статик |
Эх сурвалж нь deploy/docker-compose.yml-ийн ports: — энэ хүснэгт зөрвөл
compose зөв.
Бүгд зөвхөн loopback дээр. Гадагшаа гарах цорын ганц зам нь хостын nginx.
Скриптийн анхдагч бүрийг шалгах хэрэгтэй. Цөмийн backup.sh-ийн анхдагч
postgres контейнер нь gerege_nexus_postgres — тэр нь энэ хост дээр
хөршийнх. Анхдагчийг нь солихоо мартвал скрипт хөршийн сангаас dump авч,
хөршийн бүртгэлд «амжилттай» гэж бичнэ, нэг ч алдаагүйгээр. Нэг удаа яг тэр
болсон.
Хаалганууд¶
Хувийн муж — үргэлж нээлттэй¶
PLATFORM_ACCESS_MODE=public. eID-ээр танигдсан иргэн бүртгэлтэй болж,
өөрийн гэртээ буудаг. Миграц 00085-аас хойш шинэ данс хэний ч
байгууллагад ордоггүй тул «гэр нээлттэй» гэдэг яг энэ тохиргоотой тэнцэнэ.
Байгууллага — өөрөө сонгоно¶
Байгууллагын тохиргоо → «Хаалга»:
on_request(анхдагч) — хүсэлт илгээнэ, админ шийднэ;open— богино нэрийг мэдсэн хэн ч шууд гишүүн болно.
Шууд нэгдсэн хүн платформын анхдагч user ролийг авдаг бөгөөд тэр нь
*.read зөвшөөрлүүдийг агуулна. Хаалга нээх ба мэдээллээ харуулах хоёр нэг
зүйл. Хэн, хэзээ орсныг join_requests дээрх ACCEPTED мөр үлдээнэ;
decided_by нь NULL — хүн биш, бодлого шийдсэн.
Консол¶
Гурван хаалга дараалж: хаягийн шалгалт (CONTROL_PLANE_HOST-оос өөр нэрээр
ирсэн хүсэлт 404), нууц үг, authenticator-ийн код. Операторын бүртгэл нь
хэрэглэгчийнхээс тусдаа хүснэгт, тусдаа cookie, тусдаа audit.
Хаягийн жагсаалт (IP allowlist) одоогоор тавиагүй — операторуудын хаяг
тодрох өдөр nginx/admin.petronet.mn.conf доторх хоёр мөрийг сэргээнэ.
eID¶
Relying-party итгэмжлэл .env-д (EID_RP_UUID, EID_RP_SECRET), нэр ба
бичвэр нь тусдаа (EID_RP_NAME, EID_DISPLAY_TEXT) — иргэн апп дотроо яг
тэдгээрийг уншиж зөвшөөрдөг тул цөмийн анхдагч «Gerege Nexus»-ыг үлдээвэл
хүнээс өөрийнх нь нээгээгүй зүйлд нэвтрэхийг зөвшөөр гэж гуйна.
eID дээр бүртгэлтэй callback нь яг https://petronet.mn/auth/eid/callback
байх ёстой — платформ өөр хост, өөр замыг дуудахаасаа өмнө татгалздаг.
Нөөцлөлт¶
Өдөр бүр 03:15-д deploy/scripts/backup.sh. Сангийн pg_dump ба кластерын
role-ууд (pg_dumpall --roles-only, нууц үггүй) хоёр файлыг авч, 14 хоногоос
хуучныг цэвэрлэж, үр дүнг platform_backups-д бичнэ — консолын «Нөөцлөлт»
карт тэр мөрийг уншина. Бүтэлгүйтэл ч бүртгэгдэнэ: хэмжигдээгүй нөөцлөлт нь
нөөцлөлтгүйтэй бараг адил.
Хуулбар нь /var/backups/petronet/, энэ хостын дискэн дээр. Шифрлэн өөр
байршил руу илгээх алхам нь BACKUP_AGE_RECIPIENT (age-ийн нийтийн
түлхүүр — тавигдсан) ба BACKUP_S3_* дөрөв бүрдмэгц ажиллана. Дөрөв нь дутуу
байхад алхам бүхэлдээ алгасагдаж, nexus_backup_offsite_ok 0 гэж
хэмжигдэнэ — хуулбар өөр газар байхгүй гэдэг нь чимээгүй байх зүйл биш.
Тохируулсан байршил руу хуулж чадаагүй бол локал файл үлдэх ч ажиллалт
бүхэлдээ амжилтгүй (ok=false, exit 1). restic-ээс сэргээх алхмууд
OPERATIONS.md-д.
Сэргээх нь хаягдах сан руу, ажиллаж байгаа руу биш. Эхлээд role-ууд,
дараа нь сан (restore_check-ийг урьдчилан createdb-ээр үүсгэнэ):
gunzip -c /var/backups/petronet/petronet-roles-<огноо>.sql.gz \
| docker exec -i petronet2_postgres psql -U postgres -d postgres
gunzip -c /var/backups/petronet/petronet-<огноо>.sql.gz \
| docker exec -i petronet2_postgres psql -U postgres -d restore_check
Ажиллаж буй кластер руу role-уудыг дахин ачаалахад «already exists» алдаа гарна — хор хөнөөлгүй. Бүрэн шалгалт нь шинэ кластер дээр (OPERATIONS.md).
Ажиглалт¶
Prometheus гурван зорилт цуглуулна: энэ бүтээгдэхүүний API, хостын
node_exporter, ба PetroNet System-ийн сангийн postgres_exporter. Grafana нь
monitoring.petronet.mn дээр, хоёр самбартай.
Консолын «Платформын эрүүл мэнд» дэлгэц ижил Prometheus-аас уншина. Хөршийн стекийг хуваалцаагүй нь санаатай: консолын асуулгууд job-оор шүүдэггүй тул хоёр бүтээгдэхүүний хүсэлт нийлж тоологдох байв.
Лог ба trace (Loki, Tempo) энд байхгүй — тэдгээр нь өөрийн диск, өөрийн хадгалалтын хугацаа шаардах тусдаа шийдвэр.
Нууцууд¶
Нууцын сан (Infisical) дээрх petronet-gerege-nexus / prod төсөл нь эх
сурвалж; хостын .env нь түүний хуулбар. Долоо: сангийн нууц үг, built-in
клиентийн нууц, eID-ийн хос, Gerege Core-ийн токен, Grafana-гийн админ, ба
нөөцлөлтийн age нийтийн түлхүүр.
age-ийн хувийн түлхүүр энд ч, хостод ч байхгүй — тэр нь цөмийн төсөлд, операторт. Хостод зөвхөн нийтийнх байгаа нь санаатай: эвдэрсэн платформ өөрийн илгээсэн нөөцлөлтөө уншиж чадахгүй.
Шинэчлэлт¶
Хост дээр гараар git pull хийхгүй. Зам нь ганцхан:
commit → PR → main → CI (ci.yml) ногоон → Deploy (deploy.yml).
Deploy нь хост дээрх self-hosted runner дээр deploy/ci-deploy.sh <sha>-г
дуудна: /opt/petronet-v2/src-г тэр commit руу reset --hard хийгээд
./deploy.sh-г ажиллуулна.
deploy.sh нь backend (petronet:latest) ба бүрхүүл (petronet-web:latest,
core/frontend-ээс) хоёр образыг хост дээр барина — registry-ээс татахгүй.
Барихаас өмнө ажиллаж буй хоёр образыг :previous гэж тэмдэглэж, эрүүл мэнд /
брэнд / цөмийн хувилбарын шалгалт унавал тэдгээр рүү буцаана (миграц буцахгүй —
зөвхөн урагш). Мөн docs ба plan сайтыг дахин угсарч контейнерийг нь дахин
үүсгэнэ.
Цөм нь core/ дахь snapshot (core/SNAPSHOT) — backend ба бүрхүүл хоёулаа
түүнээс барьдаг тул хоёр тал нэг commit-ийн нэг API гэрээн дээр байна.
Шинэчлэх нь deploy/sync-core.sh / core-sync.yml.
Мартагддаг зүйлс¶
http2 on;нь тусдаа заавар байх ёстой — certbot түүнийг бичдэггүй тул шинэ vhost бүр HTTP/1.1 дээр үлддэг. Энэ хост дээр хоёр домэйн яг тэгж үлдсэн байсныг шалгалт илрүүлсэн.add_headerөв залгамжлахгүй: хүү блок дотор нэг ч байвал дээд түвшнийхийг бүгдийг нь хаяна.- Порт бүр нэг эзэнтэй. Дээрх хүснэгтийг шинэ сервис нэмэх бүрд шалгана.