跳转至

Ажиллагаа

Байршуулалт, ажиглалт, нөөцлөлт. deploy/, .github/workflows/deploy.yml ба ажиллаж байгаа суулгацаас уншиж бичигдсэн.

Баримтын төв · Архитектур · Гарын авлага


Зургаан нэр, нэг хост

Нэр Юу Ард нь
open.gerege.mn Платформ өөрөө — frontend ба /api/v1/* Next.js + Go
admin.open.gerege.mn Операторын консол — /api/platform/v1/* Мөн тэр хоёр
dwh.open.gerege.mn Дата агуулахын зураглал Статик, өөрийн контейнер
backups.open.gerege.mn Шифрлэгдсэн нөөцийн сан (MinIO) + тайлбар хуудас MinIO + nginx
monitor.open.gerege.mn Grafana Ажиглалтын стек
docs.open.gerege.mn Энэ баримт Статик, MkDocs

Хоёр урсгал өөр origin дээр байгаа нь гоо зүйн биш: cookie нь hostname-аар хязгаарлагддаг тул тусдаа нэр нь тусдаа ambient authority гэсэн үг.

Платформын нүүр хуудас эдгээрийг карт болгож харуулна. Хаягууд нь кодод биш, суулгацын орчинд (SERVICE_URL_ADMIN, _DWH, _BACKUPS, _MONITOR, _DOCS, мөн үндэсний _EID): admin.open.gerege.mn бол энэ суулгацынх, өөр хэн ч биш. Тохируулаагүй үйлчилгээ зурагдахгүй, нэг ч тохируулаагүй бол хэсэг бүхэлдээ зурагдахгүй.

Консолын хаалга нь мөн платформын landing дизайнтай: нэвтрэх маягт нь hero дотор, доор нь эрхийн загвар ба impersonation-ий нөхцөлүүд. Session-гүй ирсэн хүн ард нь юу байгааг мэдэлгүй үлдэх ёсгүй — тэр хаяг юу болохыг хэлэх нь нууц задруулах биш, нэвтрэх шалгалт нь ард нь хэвээр байна.

Статик хуудсууд контейнерт

dwh.* нь deploy/docker-compose.dwh.yml-ийн nginx:alpine контейнерээс үйлчилнэ — read-only файлын систем, no-new-privileges, зөвхөн loopback. Хостын nginx-ээс шууд файл өгч ч болох байсан (docs.* тэгдэг) ч тэр төсөл дараа нь Metabase, Cube, Postgres нэмнэ: тэдгээр нь бүгд контейнер болох тул нэгдүгээрх нь ч контейнер байсан нь хожим stack-ийн хажууд зөөхийг compose файлд мөр нэмэх ажил болгоно.

Байршуулалт

CI ногоон болсны дараа deploy.yml:

ghcr.io-д backend ба frontend image бүтээж түлхэх
   ↓  (tag = commit sha, мөн latest)
хост руу ssh: compose файл хуулах → pull → migrate → restart

Хоёр зүйл зориуд:

  • Хувилбар нь image дотор ldflags-аар шатаагдана. Тэгэхгүй бол суулгац бүр өөрийн хувилбарыг мэдэхгүй болно — каталог "platform": ">=1.1.0" шаардахад хариулах зүйлгүй.
  • Хуучныг шинэ нь бэлэн болтол буулгахгүй. GHCR дөнгөж түлхсэн хувийн image-д denied гэж хариулах нь ховор биш бөгөөд нэг удаа тэр нь тухайн ажиллагааны өөрийнх нь түлхсэн image-ийн rollout-ыг унагаасан.

Тохиргоо CI-гаас ирнэ, хостоос биш

deploy.yml нь серверийн .env-ийг ажиллагаа бүрд шинээр бичдэг — «written fresh every deploy so the server never drifts from CI». Энэ нь зөв зан төлөв: хост дээр гараар хийсэн засвар нь хаана ч бүртгэгдээгүй, хэн ч давтаж чадахгүй тохиргооны эх сурвалж болно.

Үр дагавар нь мартагдамхай: хостын .env рүү гараар нэмсэн мөр дараагийн rollout дээр арчигдана. Шинэ тохиргоо нэмэх зам нь гурван газарт бичих:

deploy.yml  env блок          ${{ vars.X }} эсвэл ${{ secrets.X }}
deploy.yml  envs: жагсаалт    ssh-action тэр хувьсагчийг дамжуулна
deploy.yml  .env heredoc      X=${X}

Нууц биш утга — нийтийн hostname, URL — нь vars, нууц нь secrets. Тавиагүй vars нь хоосон мөр болж, хэрэглэгч тал нь «тохируулаагүй» гэж уншина.

Энэ баримтыг бичих үед үйлчилгээний хаягуудыг хостын .env-д гараар нэмээд дараагийн deploy дээр алга болохыг харсны дараа л зөв газарт нь тавьсан.

Хоосон нууц чимээгүй өнгөрдөггүй. Тохируулаагүй нууц нь .env-д хоосон мөр болж бичигдэж, платформ түүгээрээ асдаг: rollout юу ч анзаарахгүй, алдаа нь тэр утгыг хамгийн түрүүнд асуусан зүйл дээр гарна. Тиймээс хоосон байж болохгүй утгуудыг эхний байт серверт хүрэхээс өмнө шалгана. Зөвхөн хоосон эсэхийг шалгаж, зөвхөн нэрийг хэвлэнэ — тавигдсаныг батлахын тулд утгыг нь echo хийдэг шалгалт бол түүнийг лог уншдаг бүх хүнд нийтэлсэн хэрэг.

Нууцын сан — secrets.gerege.mn

Нууцууд GitHub-ийн secret-ээс эсвэл Infisical-аас ирж болно. deploy.yml дахь утга бүр ${{ secrets.X || env.X }} хэлбэртэй: GitHub-д байвал түүнийг, байхгүй бол сангаас ирснийг авна.

Тэгсний ач холбогдол нь нэг нэгээр нь шилжүүлж болох явдал. Үйлдвэрлэлийн нууцыг нэг шөнөд бүхэлд нь зөөх шаардлагагүй: санд нэгийг тавь, GitHub-аас тэрийг устга, нэг rollout ажиглаж үз, дараагийнх руу шилж. Аль ч мөчид буцах зам нь secret-ээ буцааж тавих.

Нэвтрэлт нь OIDC — client secret байхгүй. GitHub ажиллагаа бүрд богино настай токен гаргаж, Infisical түүнийг шалгана. Тэгснээр «нууц хадгалах газар руу орох нууц» гэдэг асуудал огт үүсэхгүй.

Асаах: Infisical дээр machine identity үүсгээд, репод дараах variable-ууд тавина (нууц биш — эдгээр нь зөвхөн хаяг ба танигч):

INFISICAL_IDENTITY_ID      machine identity-ийн ID
INFISICAL_PROJECT_SLUG     төслийн slug
INFISICAL_DOMAIN           анхдагч https://secrets.gerege.mn
INFISICAL_ENV_SLUG         анхдагч prod
INFISICAL_SECRET_PATH      анхдагч /

INFISICAL_IDENTITY_ID тавиагүй бол алхам ажиллахгүй бөгөөд бүх зүйл өмнөх шигээ GitHub-ийн secret-ээс ирнэ.

Санд ордоггүй зүйлс. DEPLOY_SSH_KEY, DEPLOY_HOST, DEPLOY_USER нь GitHub-д үлдэнэ: тэдгээр нь хост руу хүрэх зам бөгөөд санд хүрэхээс өмнө хэрэгтэй болдог. GITHUB_TOKEN нь GitHub-ийн өөрийнх.

Санд байх ёстой ч CI-д хэзээ ч ордоггүй зүйлс. Хостын дээрх нөөцлөлт, ажиглалтын түлхүүрүүд — ялангуяа age-ийн хувийн түлхүүр — нь deploy-гоор дамждаггүй. Тэдгээрийн хувьд сан нь цорын ганц хуулбар: хост алдвал сэргээх эх сурвалж өөр байхгүй.

Юу хаана байна

Хариулт нь нэг өгүүлбэр: суулгацын бүх нууц secrets.gerege.mn дээр байдаг. Хост дээрх файлууд нь тэдгээрийн ажлын хуулбар болохоос эх сурвалж биш. 2026-09-03-нд хост дахин суулгагдахад энэ ялгаа үнэ цэнээ харууллаа: санд байсан нь бүтнээрээ үлдсэн, зөвхөн хост дээр байсан нь бүгд алга болсон.

Зам Хэн уншдаг Юу байдаг
prod:/ deploy.yml (OIDC) Платформ өөрөө ажиллахад хэрэгтэй нь — POSTGRES_PASSWORD, EID_RP_*, INTEGRATION_ENCRYPTION_KEY, GEREGE_CORE_TOKEN, SSO_DEFAULT_CLIENT_SECRET, GOOGLE_LOGIN_*, GEMINI_API_KEY, APPSTORE_PUBLIC_KEY, CONTROL_PLANE_ALLOWED_CIDRS, AGE-SECRET-KEY
Archive-ийн prod:/<суулгац> хэн ч биш — зөвхөн хүн Суулгац бүрийн хостын дээрх .env бүхэлдээ, өөр төсөл дотор. Доорх жагсаалтыг үз
GitHub secret deploy.yml DEPLOY_SSH_KEY, DEPLOY_HOST, DEPLOY_USER — хост руу хүрэх зам, санд хүрэхээс өмнө хэрэгтэй

open-gerege-nexus төсөл нь зөвхөн энэ платформын CI-ийн нууцыг барина. Гараар суудаг бүхний нууц нь Archive гэсэн ӨӨР төсөлд байна — тэр төслийг ямар ч workflow уншдаггүй, тиймээс тэдгээр нь CI-ийн орчинд хэзээ ч гарч ирэх боломжгүй. (Эхэндээ эдгээрийг энэ төслийн дэд хавтсууд болгосон; Infisical-ийн алхам зөвхөн INFISICAL_SECRET_PATH дээрхийг татдаг тул тэр нь ч ажиллах байсан, гэхдээ тусдаа төсөл нь эрхийн хувьд ч тусгаарладаг.)

Суулгац бүрийн хавтас — Archive төсөл

2026-09-03-нд хүрч болох найман хостын .env бүхэлдээ санд орлоо. Хавтасны нэр нь суулгацынх; хост дээрх файл нь одооноос ажлын хуулбар бөгөөд толгойдоо үүнийг хэлсэн мөртэй.

Infisical дээр өөр хоёр төсөл бас байна — petronet-gerege-nexus ба tsm-gerege-mn — тэдгээр нь тухайн репод зориулагдсан бөгөөд энд хамаарахгүй.

Хавтас Хост Файл
nexus, tsm 38.180.145.75 .env.monitoring, .env.backups, /etc/default/nexus-backup, /opt/tsm/.env
appstore, business, developer, benzin-app, appstore-legacy, mcp 38.180.146.236 /opt/<нэр>/.env
dgov, sso-dgov 38.180.243.138 /opt/open-dgov-mn/.env, /opt/sso-dgov-mn/deploy/.env
petronet 38.180.120.144 /opt/petronet/.env
geregeapp 38.180.251.213 /opt/app-nexus/.env
eduge 38.180.137.169 /opt/eduge-nexus/.env, .admin-password
eid 38.180.117.155 /opt/eid-nexus/.env

Хоёр хост дутуу: 38.180.137.241 (Benzin, OpenSandbox) ба 38.180.254.231 (POS) руу бидний барьж байгаа ямар ч түлхүүр хүрэхгүй. Хостынгоо самбараар дамжуулан түлхүүр сэргээх хүртэл тэдгээрийн нууц зөвхөн тэр хоёр машин дээр байна.

_EMPTY_ON_HOST. Infisical хоосон утга хүлээж авдаггүй бөгөөд нэгийг таарахад бүх импортыг татгалздаг. Тиймээс хоосон түлхүүрүүд хасагдаж, нэрс нь энэ нэг утганд хадгалагдав — «энэ түлхүүр хост дээр байгаа бөгөөд зориуд хоосон» гэдэг нь алдаж болохгүй мэдээлэл.

AGE-SECRET-KEY нь / дээр байгаа нь зориуд. Нөөцлөлтийг задлах цорын ганц түлхүүр бөгөөд хост дээр зөвхөн түүний нийтийн хувь (BACKUP_AGE_RECIPIENT) байдаг. Хост эвдэрсэн ч өөрийн илгээснээ уншиж чадахгүй; сан алдвал бүх суулгацын нөөц бүхэлдээ уншигдахаа болино. Хоёр дахь хуулбар нь операторын password manager-т байх ёстой, өөр хаана ч биш.

Шинэ нууц үүсгэхийн өмнө санг хар. 2026-09-03-нд хостыг дахин барихдаа шинэ age хос үүсгэсэн нь илүүц ажил байв — операторын түлхүүр санд бүтэн байсан бөгөөд түүнийг олох нь infisical secrets --env=prod --path=/ гэсэн нэг тушаал. Хоёр дахь түлхүүр нь аюулгүй байдал нэмдэггүй, зөвхөн аль нь аль dump-ыг задалдаг вэ гэсэн асуулт нэмдэг.

Ажиглалт

deploy/docker-compose.monitoring.yml — тусдаа стек, тусдаа сүлжээ, платформын сүлжээнд зөвхөн scrape хийхээр холбогдоно.

Хадгалах хугацаа
Prometheus 3.1 Хэмжүүр 60 хоног / 20 GB
Loki 3.4 Лог 31 хоног
Tempo 2.7 Trace 72 цаг
Alloy 1.7 Цуглуулагч
Grafana 11.5 Дэлгэц
Alertmanager 0.28 Сэрэмжлүүлэг

Экспортерууд: node_exporter, cAdvisor, postgres_exporter, redis_exporter.

Trace 72 цаг байгаа шалтгаан: trace нь хүсэлт болсноос хойш минут, эсвэл цагийн дотор уншигддаг. Долоо хоногийн настай trace-ыг хэн ч нээдэггүй.

Хэмжүүр

Хэмжүүр бүр OpenTelemetry-ийн SDK-аар дамжиж, Prometheus exporter-ээр /metrics дээр гарна. HTTP-ийнх нь semantic convention-ыг дагана:

http_server_request_duration_seconds{http_request_method,http_route,http_response_status_code}

Хүсэлтийн тоо нь тусдаа counter биш — тэр гистограммын _count цуврал.

http.request.method нь хаалттай олонлог. Танихгүй үйл үг _OTHER болж нугалагдана: PROPFIND гэж дуудсан сканнер time series үүсгэх ёсгүй.

Гадаад систем бүр нэг histogram-аар хэмжигдэнэ — external_request_duration_seconds{system,operation,status} — системийн нэр нь мөн адил хаалттай олонлог, танихгүй нь other.

Exemplar

Trace асаалттай үед гистограммын сэмпл бүр trace_id авч явна. Латенси графикийн удаан цэг дээр дарахад Grafana тэр яг тэр хүсэлтийн trace-ыг нээнэ — «аль хүсэлт удаан байсан бэ» гэдгийг таамаглах хэрэггүй.

/metrics нь OpenMetrics хэлбэрээр үйлчилдэг байх ёстой, эс бөгөөс exemplar дамжихгүй.

Лог

Alloy Docker-ийн лог цуглуулж Loki руу өгнө. Backend нь slog-оор JSON бичдэг тул | json ажиллана.

Хоёр урхи, хоёулаа энэ суулгац дээр бодитоор гарсан:

  • LogQL-ийн шүүлт том жижиг үсэг ялгана. |= "audit" нь юу ч олохгүй — бичигдсэн зүйл нь "msg":"AUDIT_EVENT".
  • $__rate_interval нь зөвхөн Prometheus-ийнх. Loki дээр $__auto.

Мөн: Grafana нь панелийг панелийн датасурс дээр ажиллуулдаг, target-ийнх дээр биш. Хоёр нь зөрвөл LogQL нь Prometheus руу очиж parse алдаа өгнө.

Дэлгэцүүд

deploy/monitoring/grafana/dashboards/ — provisioning-оор ирдэг, гараар үүсгэдэггүй:

api-overview · infrastructure · logs · security · resilience · external-systems · monitoring-self

Сүүлийнх нь хамгийн чухал: ажиглалт өөрөө ажиллаж байгаа эсэх. Унтарсан Prometheus нь бүх зүйл хэвийн байгаа мэт харагддаг.

Сэрэмжлүүлэг

31 дүрэм, зургаан файлд. Хамрах хүрээ:

  • API — унтарсан, латенси, алдааны төсвийн шаталт (хурдан / удаан)
  • Дэд бүтэц — диск, санах ой, Postgres, Redis, контейнерын дахин эхлэл, TLS
  • Консол — нэвтрэлтийн бүтэлгүйтэл, түгжээ, break-glass ашиглалт, бүртгэгдээгүй бичилт
  • Гадаад систем — удаан, доройтсон, бүтэлгүй
  • Нөөцлөлт — бүтэлгүй, хуучирсан, хэзээ ч харагдаагүй, хостоос гараагүй
  • Ажиглалт өөрөө — Alertmanager мэдэгдэхгүй байна, дүрэм тооцоолж чадахгүй байна, Loki лог татгалзаж байна, target унтарсан

NexusTLSExpiryUnknown нь тусгай: тэр нь «гэрчилгээ дуусах гэж байна» гэсэн үг биш, «хэн ч хэмжихгүй байна» гэсэн үг. Хугацааг бичдэг cron ажил нь гараар суулгагддаг бөгөөд нэг хост дээр огт суулгагдаагүй байсан.

Брэндлэлт ба Монгол хэл

Ажиглалтын домэйн нь платформын нэг хэсэг мэт харагдах ёстой: bare домэйн дээр landing хуудас, Grafana дээр Gerege лого, нэр, tab icon, цагаан нэвтрэх карт, монгол хэл. Grafana OSS-д брэндлэх цэг байхгүй (white labeling нь Enterprise) тул бүгд nginx дээр хийгдэнэ:

MONITOR_DOMAIN=monitor.open.gerege.mn deploy/scripts/setup_monitor_branding.sh

Скрипт нь ажиллаж буй Grafana-аас хоёр webpack chunk-ийн нэрийг уншиж (нэр нь агуулгын hash агуулдаг), монгол орчуулгын chunk-ийг deploy/monitoring/grafana/branding/i18n/mn.txt-ээс барьж, хэлний жагсаалт дахь SvenskaМонгол болгож, /var/www/monitor руу landing хуудас, хэв маяг, скрипт, логог тавиад nginx-ийн snippet-ийг үүсгэнэ. Төгсгөлд нь долоон шалгалтыг домэйнээр дамжуулан хийнэ — файл байрандаа байгаа эсэх биш, браузарт юу ирж байгааг.

Гурван зүйлийг санах:

  • Grafana шинэчлэх бүрд дахин ажиллуулна. chunk-ийн hash өөрчлөгдөхөд орлуулалт таарахаа болино; тэр үед швед хэл эргэж ирнэ, өөр юу ч эвдрэхгүй.
  • Монгол хэл нь sv-SE-ийн үүрэнд сууна (Grafana-д mn locale байхгүй). Тиймээс GRAFANA_DEFAULT_LANGUAGE=sv-SE нь зөвхөн скрипт ажилласан хостод зөв.
  • Орчуулга хэсэгчилсэн (255 түлхүүр). Дутуу түлхүүр англи руугаа буцдаг тул mn.txt-д мөр нэмээд скриптийг дахин ажиллуулахад л хангалттай.

Нөөцлөлт

deploy/scripts/backup.sh, cron дээр өдөр бүр.

pg_dump → хуучныг цэвэрлэх → platform_backups-д мөр бичих
        → node_exporter-ийн textfile руу хэмжүүр бичих
        → age-ээр шифрлэж off-site руу илгээх

Гурав дахь алхам нь консол уншдаг мөр. Дөрөв дэх нь Prometheus уншдаг — шөнө дунд хэн нэгэнд сэрэмжлүүлэг илгээж чадах цорын ганц хувилбар. Хэмжигдэхгүй нөөцлөлт нь нөөцлөлт байхгүйтэй бараг адил: cron-ий чимээгүй бүтэлгүйтэл нь сэргээх өдрөө л илэрдэг.

Хостод зөвхөн age-ийн нийтийн түлхүүр байна. Эвдэрсэн платформ өөрийн илгээсэн зүйлээ уншиж чадахгүй; хувийн түлхүүр нь операторт байна. Түүнийг хост дээр үлдээвэл шифрлэлт нь утгагүй; түүнийг алдвал нөөцлөлт нь утгагүй.

Off-site сан нь MinIO, объектын хувилбарлалт асаалттай, байршуулалтын түлхүүр нь зөвхөн нэмэх эрхтэй. Тэр нь эвдэрсэн хост нь өөрийн өмнөх нөөцлөлтүүдийг устгаж чадахгүй гэсэн үг.

Хэмжүүр:

nexus_backup_last_run_timestamp_seconds
nexus_backup_last_success_timestamp_seconds
nexus_backup_last_size_bytes
nexus_backup_last_ok
nexus_backup_offsite_ok

Бүтэлгүйтсэн ажиллагаа нь өмнөх амжилтын мөчийг хадгална — эс бөгөөс нэг бүтэлгүйтэл нь «хэзээ ч амжилттай болоогүй»-тэй ялгагдахаа болино. Тохируулаагүй суулгац дээр offsite_ok нь 0 хэвээр байна, тэр нь зөв: хуулбар өөр газар байхгүй гэдэг нь хэмжигдэх ёстой баримт.

Сэргээлт

Нөөцлөлт нь сэргээгдэх хүртэл нөөцлөлт биш. Шалгах арга:

age -d -i key.txt backup.sql.gz.age | gunzip > restore.sql
createdb restore_check && psql restore_check < restore.sql
psql restore_check -c "select count(*) from information_schema.tables
                        where table_schema in ('workspace','registry','operator')"

Хаягдах өгөгдлийн сан руу — ажиллаж байгаа руу биш.

nginx-ийн хоёр урхи

Хоёулаа энэ хост дээр бодитоор гарсан, хоёулаа хариу 200 хэвээр байхад чимээгүй ажилладаг. Тиймээс curl -I нь vhost нэмсний дараах заавал хийх алхам.

add_header өв залгамжлахгүй. Хүү блок дотор НЭГ ч add_header байвал дээд түвшнийхийг нь бүгдийг нь хаяна. location / дотор Cache-Control нэмсэн нь server түвшний дөрвөн толгойг — CSP, HSTS, X-Frame-Options, X-Content-Type-Options — чимээгүй унтраасан. Хуудас зөв харагдсаар, хариу 200 хэвээр; зөвхөн толгойг нь уншиж байж мэдэгдэнэ. Шийдэл нь бүх add_header-ийг нэг түвшинд байлгах.

Certbot HTTP/2 бичдэггүй. Тэр нь listen 443 ssl мөрийг өөрөө бичдэг ба протоколыг нэмдэггүй. Үр дүнд нь 2026-08-28-ны HTTP/2 шилжилтийн дараа үүсгэсэн vhost бүр — docs, backups, monitor, cp — HTTP/1.1 дээр үлдсэн байв. http2 on; нь тусдаа заавар байх ёстой: тэгвэл гэрчилгээ шинэчлэх бүрд алга болохгүй.

curl -s -o /dev/null -w "http/%{http_version} %{http_code}\n" https://<нэр>/
curl -sI https://<нэр>/ | grep -iE 'content-security|strict-transport|x-frame'

Олон байгууллагыг нэг дор нээх

Консолын маягт нэгийг нээдэг. Суулгац эхлэх өдөр — зохицуулагч хоёр зуун лицензтэй компанийг, яам харьяа агентлагуудаа оруулах — тэр нь ажлын урсгал биш, хэн ч зарцуулахгүй үдэш болно. tenant-bootstrap ч тусалдаггүй: тэр нь эхний ажиллуулалтын хэрэгсэл бөгөөд байгууллага үүссэний дараа зориуд татгалздаг.

POST /api/platform/v1/tenants/bulk
{"organisations":[{"name":"…","slug":"…","admin_email":"…","reason":"…"}, …]}

Гурван шинж чанар, ач холбогдлын дарааллаар:

  • Гүйлгээ БИШ. 137 дахь мөр унасан нь өмнөх 136 байгууллагыг устгах ёсгүй. Мөр бүр өөрийн аудитын бичлэгтэй, өөрийн үйлдэл — оператор маягтыг 200 удаа илгээсэнтэй яг адил.
  • Мөр бүр тайлагнана. Хариу нь тоо ч биш, эхний алдаа ч биш, үр дүнгийн жагсаалт. 200 мөр илгээсэн хүн алийг нь буугаагүйг, яагаад гэдгийг мэдэх ёстой.
  • Дахин илгээх нь аюулгүй. Байгаа slug нь exists, алдаа биш. Файл засагдаад дахин илгээгддэг; хоёр дахь ажиллуулалт нь шинэ хоёр мөрийг нуусан алдааны хана байвал гурав дахь удаа хэн ч илгээхгүй.

Нэг хүсэлтэд дээд тал нь 200 байгууллага. Энэ нь гүйцэтгэлийн хязгаар биш, дэлбэрэлтийн радиус: дуудагч талын давталтын алдаа нь татгалзсан хүсэлт байх ёстой болохоос, тус бүрдээ хоёр superadmin шаардах дөрвөн мянган байгууллага биш.

CSV, Excel, файл байхгүй. Консол JSON ярьдаг бөгөөд компанийн жагсаалт барьсан хүн түүнийг хөрвүүлж чадна; энд задлагч бичих нь кодчиллын алдаа амьдрах хоёр дахь газар болох бөгөөд доор нь энэ endpoint хэвээр хэрэгтэй.

Гараар хийгддэг зүйлс

Байршуулалт автомат, гэхдээ эдгээр нь биш. Шинэ хост дээр мартагддаг зүйлс — тэдгээрийн нууц бүр prod:/<суулгац> дээр байдаг тул шинийг зохиохын өмнө тэндээс хар:

  • backup.sh-ийн cron бичлэг
  • TLS дуусах хугацааг бичдэг cron ажил. Скрипт нь одоо репод байна — deploy/scripts/nexus-tls-expiry.sh, суулгах гурван мөр нь түүний толгойд. Өмнө нь энэ нь зөвхөн баримт доторх хуулж тавих блок байсан бөгөөд шинэ хост бүр түүнгүйгээр босдог байв: хэмжигдээгүй нь эрүүлтэй яг адил харагддаг
  • Docker 29 дээр cAdvisor-ын containerd тохиргоо (--containerd-namespace=moby ба pid: host) — үүнгүйгээр нэг л цуврал экспортлогдоно, мөн энэ нь дахин эхлүүлэхийг шаарддаг, дахин үүсгэхийг биш
  • Хуучин Docker image-ийн цэвэрлэгээ. ghcr-retention.yml нь GHCR талыг цэвэрлэдэг ч хостын дискийг цэвэрлэдэггүй: deploy бүр хоёр image нэмнэ ба тэдгээр нь өөрөө хэзээ ч явахгүй. Гарын авлага.

Дэлгэрэнгүй алхмуудыг Гарын авлага.