nessie

L-installazzjoni ta’ Nessie

Tħaddem Nessie fuq infrastruttura li tagħżel int, minn magna waħda sa cloud immaniġġjat.

Dak li għandek bżonn qabel tibda

Nessie huwa monorepo ta’ pnpm b’servizzi Node u żewġ bundles statiċi. Kif tħaddem, hemm erba’ affarijiet li jridu jeżistu l-ewwel.

  • PostgreSQL bil-pgvector. Mhux fakultattiv, u ma jistax jiġi sostitwit — il-migrazzjonijiet iħaddmu CREATE EXTENSION vector u joħolqu kolonni vector(1024). Il-produzzjoni tuża pgvector/pgvector:pg17.
  • Node 22 u pnpm. Kull Dockerfile f’infrastructure/docker/ jinbena fuq node:22-slim, u r-repożitorju jiffissa l-maniġer tal-pakketti tiegħu fil-package.json tal-għeruq (pnpm@10.22.0).
  • Endpoint tal-mudell kompatibbli ma’ OpenAI u ċavetta għalih. L-aġenti u l-embeddings kollha jgħaddu minnu. Ara “Il-konfigurazzjoni tal-inferenza” hawn taħt.
  • Ħażna tal-oġġetti kompatibbli ma’ S3, għal kull deployment li mhuwiex l-installazzjoni lokali għall-iżvilupp. Uploads fuq disk lokali jiġu rrifjutati barra l-modalità local, u dak ir-rifjut huwa falliment fl-istart u mhux bootjar iddegradat — ara “Magna waħda jew cloud ġestit”.

Docker u reverse proxy huma meħtieġa għat-triq tal-kontenituri deskritta aktar ’il quddiem, u dominju u TLS għal kull ħaġa li tintlaħaq mill-internet.

Id-dimensjonament tal-hardware — il-minimu ta’ CPU, memorja u disk għal għadd partikolari ta’ nies — mhuwiex imsemmi xejn fir-repożitorju, għalhekk din il-paġna wkoll ma tgħidx.

Il-komponenti, u kif jaqblu ma’ xulxin

KomponentX’inhuIngress
api/L-API tal-HTTP/WebSocket b’Fastify. Kull klijent jitkellem ma’ dan u ma’ xejn ieħor.Iva
worker/Orkestrazzjoni tal-aġenti u eżekuzzjonijiet fl-isfond. Jistaqsi l-kju tax-xogħlijiet; ma jorbot ebda port.Le
admin/L-interface tal-prodott — bundle statiku mibni b’Vite u mqassam minn nginx.Iva
web/Is-sit pubbliku. Statiku, fakultattiv, u m’huwiex marbut mat-tħaddim tal-prodott.Iva
PostgreSQLId-database, il-kju tax-xogħlijiet u l-bus tal-ħin reali, it-tlieta flimkien.Le
Ħażna tal-oġġettiAttachments, avatars u fajls tal-knowledge base. Kompatibbli ma’ S3; MinIO fil-produzzjoni.Le
gateway/Relay fakultattiv tal-push għal APNs u FCM. Mitfi sakemm tattivah b’mod deliberat.Iva

L-API u l-worker huma immaġni waħda. Iż-żewġ pakketti huma marbuta ħafna, għalhekk Dockerfile.app jibni l-proġett kollu darba, u l-kontenitur tal-worker jibdel il-kmand għal node worker/dist/index.js. Fil-modalità local ma hemm l-ebda kontenitur tal-worker: l-API tħaddem il-worker ġewwa l-proċess tagħha stess.

M’hemm l-ebda Redis. Il-kju tax-xogħlijiet u t-transport tal-ħin reali huma t-tnejn mibnija fuq Postgres, b’deċiżjoni u mhux b’nuqqas ta’ ħsieb — il-kodiċi tal-Google Cloud jneħħi l-modules tal-Pub/Sub u tar-Redis għall-istess raġuni.

Portijiet

Fl-iżvilupp lokali l-API hija fuq 5454 u l-admin fuq 5455 bħala default. Checkout jista’ jieħu par tiegħu billi jissettja NESSIE_API_PORT u NESSIE_ADMIN_PORT, fl-ambjent jew fil-.env tar-repożitorju; kull għodda fir-repożitorju, inklużi s-suites tat-test tal-browser, taqra l-istess żewġ valuri. Agħżel il-par qabel tibda u żommu: jekk tmexxi servizz li jkun diġà qed jaħdem lejn port ieħor, l-admin jibqa’ jkellem l-API ħażina.

Il-produzzjoni hija differenti u ma tinbidilx b’din ir-regola. Il-kontenitur tal-API jisma’ internament fuq 5554 (imwaħħal b’NESSIE_API_PORT) u r-relay tal-push fuq 5556, it-tnejn wara l-reverse proxy.

Il-ħidma fuq magna waħda, għall-iżvilupp

Ir-repożitorju jibgħat fajl Compose b’database biss fih, u dak huwa kollu li jeħtieġ il-ħidma lokali.

pnpm install
docker compose -f infrastructure/compose/docker-compose.yml up -d postgres

Dak il-kontenitur jippubblika Postgres fuq 55432 bl-utent, il-password u d-database kollha msemmija nessie. Poġġi l-connection string f’.env fil-għeruq tar-repożitorju — l-iskrittura tal-iżvilupp tal-API taqrah — imbagħad applika l-migrazzjonijiet u ibni l-worker darba, għax fil-modalità lokali l-API tgħabbi l-worker mill-dist mibni tiegħu:

DATABASE_URL=postgresql://nessie:nessie@localhost:55432/nessie

pnpm --filter @nessie/api prisma:migrate:deploy
pnpm --filter @nessie/worker build
pnpm dev

pnpm dev iħaddem l-API u l-admin flimkien b’hot reload, fuq 5454 u 5455. Iċċekkja li l-API weġbet għal GET /api/health.

Postgres, u l-ħtieġa tal-pgvector

Tliet estensjonijiet jinħolqu mill-migrazzjonijiet infushom — vector, pg_trgm u pgcrypto — għalhekk ir-rwol li jħaddimhom irid ikun jista’ joħloq estensjonijiet. Fuq Postgres ġestit din hija l-ewwel ħaġa li għandek tiċċekkja.

Il-wisa’ tal-vector hija parti mill-iskema, mhux settaġġ. thoughts.embedding, thought_recalls.query_embedding u knowledge_page_chunks.embedding huma kolonni vector(N), u N huwa stabbilit darba bħala EMBEDDING_DIMENSIONS f’packages/schemas/src/embedding.ts — bħalissa 1024, il-wisa’ nattiva tal-mudell tal-embeddings li l-produzzjoni tuża. Kull talba ta’ embedding tibgħat dik il-wisa’, għalhekk provider li jweġib b’wisa’ oħra jfalli b’mod ċar minflok ma jikteb vectors li d-database tiċħad. Li tmur għal mudell tal-embeddings b’wisa’ differenti tfisser li tibdel dik il-kostanti, tikteb migrazzjoni li terġa’ tiddefinixxi t-tliet kolonni, u terġa’ tagħmel l-embeddings kollha: vectors ta’ wisa’ differenti ma jinqalbux, għalhekk il-migrazzjoni tħallihom null minflok tqattagħhom.

Jekk tħaddem Nessie flimkien ma’ applikazzjonijiet oħra fuq network Docker kondiviż, agħti lill-kontenitur tad-database isem differenti. Is-service ta’ Compose tal-proġett jismu nessie-postgres u qatt postgres, għax l-isem tas-service isir alias tad-DNS fuq in-network kondiviż, u kollizzjoni tagħmel li postgres:5432 jalterna bejn żewġ databases.

Konfigurazzjoni

Il-konfigurazzjoni tal-ħin tal-eżekuzzjoni hija f’saffi: fajl nessie.config.json imqiegħed read-only fl-API u fil-worker, bl-environment variables fuqu. Il-mappa bejniethom hija ConfigEnvMap f’packages/config, u hija l-lista awtoritattiva.

NESSIE_MODE jagħżel il-forma tad-deployment: local (id-default, u t-triq tal-iżviluppatur), hosted, jew selfHosted — dak li jissettja installazzjoni self-hosted. Jiddiżattiva l-dev login u jeħtieġ allowlist tal-CORS.

Dawn huma s-settaġġi li deployment selfHosted ma jibdiex, jew ma jaħdimx, mingħajrhom:

VarjabbliGħaliex
DATABASE_URL / NESSIE_DB_URLIs-connection string tal-Postgres.
NESSIE_AUTH_SECRET32 bytes bil-hex (openssl rand -hex 32). Jiffirma s-sessjonijiet u t-tokens tal-bootstrap. L-istart jitfa’ eċċezzjoni mingħajrha barra mill-modalità local, u trid tkun l-istess valur fuq kull replika u matul id-deployments kollha, inkella s-sessjonijiet kollha jintemmu f’kull rilaxx.
NESSIE_ENCRYPTION_KEY_RING, NESSIE_ENCRYPTION_ACTIVE_KEY_VERSIONKey ring f’JSON u t-tikketta li tagħżel ir-root attiv, meħtieġa barra mill-modalità local. Dan huwa root separat mis-sigriet tal-iffirmar — il-key ring jiċċifra kull sigriet durabbli li Nessie taħżen. Tużax wieħed bħala l-ieħor.
NESSIE_STORAGE_PROVIDERTrid tkun s3. filesystem hija d-default u tiġi rrifjutata fil-modalitajiet hosted u selfHosted, għalhekk deployment li ma jsettja xejn hawnhekk jieqaf milli jibda, minflok ma jikteb uploads fuq disk li ebda kontenitur ieħor ma jista’ jaqra.
NESSIE_CORS_ORIGINSL-origin tal-admin. L-admin u l-API huma origins separati, u l-API trid tkun allowlist għall-origin li tservi.
NESSIE_API_PUBLIC_URL, NESSIE_ADMIN_PUBLIC_URLJintuża biex jinħolqu redirect URIs tal-OAuth barra minn talba HTTP. L-API jitfa’ eċċezzjoni fil-ħin tat-talba mingħajr l-ewwel wieħed.
NESSIE_MODEL_PROVIDER, _BASE_URL, _API_KEYFejn tmur l-inferenza. Araw hawn taħt.

infrastructure/compose/.env.prod.example fih il-forma eżatta tagħhom kollha, bil-blokki fakultattivi — ħażna tal-oġġetti, vault tas-sigrieti, SSO, posta konnessa — imkommentati fejn jinsabu. Il-lista sħiħa, inklużi s-settaġġi fakultattivi kollha, hija docs/deployment/configuration.md.

Id-deployment b’Docker Compose

Ikopja .env.prod.example bħala .env ħdejn docker-compose.prod.yml u imlih, imbagħad ġib d-database fuq, ibni, applika l-migrazzjonijiet u ħaddem is-servizzi. L-ordni hija importanti: il-migrazzjonijiet u s-seeds jaħdmu kontra database li diġà tkun qed tiffunzjona, qabel ma xi servizz jibda jservi.

COMPOSE="docker compose -f infrastructure/compose/docker-compose.prod.yml"

bash infrastructure/compose/ensure-encryption-key-ring.sh infrastructure/compose/.env
$COMPOSE up -d nessie-postgres
$COMPOSE build nessie-api nessie-admin nessie-web
$COMPOSE run --rm --no-deps nessie-api pnpm --filter @nessie/api prisma:migrate:deploy
$COMPOSE run --rm --no-deps nessie-api pnpm --filter @nessie/api seed:connectors
$COMPOSE run --rm --no-deps nessie-api pnpm --filter @nessie/api seed:apps
$COMPOSE run --rm --no-deps nessie-api pnpm --filter @nessie/api reconcile
$COMPOSE up -d

Id-Dockerfiles tal-produzzjoni jħaddmu l-lint ta’ kull pakkett qabel ma jinbena, għalhekk falliment tal-lint huwa falliment tal-bini.

Il-pass tar-reconcile mhux fakultattiv

reconcile jiżra’ r-regoli tal-politika default għal kull organizzazzjoni u jimla lura l-permessi tal-għodod tal-MCP protett u dawk tal-Personal Assistant. L-API kien jagħmel dan waqt il-bootjar fuq kull replika; issa jikkonnettja, jisma’, u ma jagħmel xejn ieħor, għalhekk mingħajr dan il-pass l-ewwel organizzazzjoni ma jkollha l-ebda regola tal-politika u kull rbit ta’ aġent jiġi miċħud. Huwa idempotenti, għalhekk it-tħaddim tiegħu f’kull deployment ma jagħmel l-ebda ħsara — u l-aġġornament magħmul b’idejn irid jgħaddi minn dan il-pass wkoll.

L-ewwel kont tas-sid

Installazzjoni selfHosted ġdida m’għandha l-ebda utent, għalhekk l-API joħloq token ta’ bootstrap għal darba waħda u jikteb link tal-issettjar fil-log. It-token jgħix fil-Postgres mhux f’proċess, għalhekk kull replika taqbel dwaru.

docker compose -f infrastructure/compose/docker-compose.prod.yml logs nessie-api 2>&1 | grep bootstrap

Iftaħ https://<your-admin-host>/bootstrap?token=<token> u oħloq il-kont tas-sid. It-token jiskadi wara 15-il minuta; erġa’ ħaddem is-servizz tal-API biex joħloq wieħed ġdid.

Jekk tikkonfigura SSO, m’hemm l-ebda pass ta’ bootstrap. Il-modalità bootstrap titwaqqaf fl-istess ħin li jiġi attivat provider estern tal-awtentikazzjoni — inkella tieħu f’idejha l-iskrin tad-dħul — u l-ewwel persuna li tidħol permezz tal-SSO tibbootstrapja t-tim default u ssir is-sid tiegħu.

Il-konfigurazzjoni tal-inferenza

Il-chat hija kompatibbli ma’ OpenAI. NESSIE_MODEL_BASE_URL huwa l-endpoint, NESSIE_MODEL_API_KEY il-bearer, u NESSIE_MODEL_PROVIDER isemmi l-adapter — Nessie jikkompila adapters għal openai, kimi u deepseek, u jilħaq kull ħaġa oħra permezz tal-konnettur ġenerali kompatibbli ma’ OpenAI. NESSIE_MODEL_NAME jistabbilixxi l-mudell default tad-deployment, li l-għażla individwali tal-mudell ta’ aġent tibqa’ tegħlbu.

L-embeddings jiġu rrutati separatament, għax il-provider tal-chat jista’ ma jservi xejn minnhom — DeepSeek, per eżempju, m’għandux endpoint tal-embeddings. Kull field NESSIE_EMBEDDING_* mhux issettjat jieħu mill-provider tal-chat, għalhekk deployment li ma jsettja xejn minnhom jagħmel l-embeddings permezz tal-endpoint tal-chat. Settja NESSIE_EMBEDDING_PROVIDER, NESSIE_EMBEDDING_MODEL u, fuq proxy li jgħaddi skont is-service, is-segment tas-service, meta l-provider tal-chat ma jistax jagħmel embeddings. Jekk dan isir ħażin, jiġri fil-moħbi u mhux b’mod ċar: il-memorja tal-recall u t-tfittxija tal-knowledge base jaqgħu għal kanal lessikali u jkomplu, filwaqt li jiktbu kb_search: query embedding failed fil-log.

Il-kontabilità tal-ispiża ta’ Nessie stess — il-ledger tat-token għal kull organizzazzjoni u l-gate tal-budget — ma tinbidilx skont liema endpoint tindikalu, u taħdem bl-istess mod kemm jekk l-attribuzzjoni ffirmata għal kull sejħa tkun ikkonfigurata kif ukoll jekk le.

Id-dħul

Nessie jawtentika lin-nies permezz ta’ UnlikeOtherAI, li jamministra wkoll l-istruttura tal-organizzazzjoni u tat-tim. Il-paġna tad-dħul tal-admin turi buttuna waħda “Login / Register”.

L-integrazzjoni hija fluss config-JWT u mhux OIDC standard: l-API jservi dokument ta’ konfigurazzjoni ffirmat b’RS256 fuq GET /api/auth/sso/config, u l-JWKS korrispondenti fuq GET /.well-known/jwks.json, it-tnejn fuq l-host tal-API. Biex tistabbilixxi dan, hemm sekwenza waħda li ssir darba: iġġenera par ta’ ċwievet RSA-2048 u settja UOA_CONFIG_JWT_PRIVATE_KEY_B64, UOA_CONFIG_JWT_KID, UOA_DOMAIN, UOA_CONFIG_URL, UOA_JWKS_URL, UOA_REDIRECT_URL u UOA_CONTACT_EMAIL; ikklikkja l-buttuna darba, li tiftaħ talba għall-integrazzjoni; ħalluh jiġi approvat, u dan jibgħat link għal darba fl-indirizz tal-kuntatt, li fih is-sigriet tal-klijent; settja UOA_CLIENT_SECRET u erġa’ ħaddem l-API. Il-kid trid tkun unika għal kull dominju.

Wara dominju, b’TLS

Deployment jservi tliet ismijiet: is-sit pubbliku, l-admin u l-API. L-origins tal-admin u tal-API mhumiex intercambjabbli. Dockerfile.admin jinkorpora VITE_API_BASE_URL fil-bundle waqt il-bini, għalhekk kull artifact tal-admin mibni — inkluż kull bini tad-desktop li jġorrah — irid jinbena kontra l-origin tal-API. Jekk tibnih kontra l-origin tal-admin innifsu, /api/auth/providers jirrisolvi għall-qafas HTML tal-admin, u l-login jibqa’ mwaħħal fuq “Loading providers...”.

Il-produzzjoni ttemm it-TLS f’Caddy, li jikseb ċertifikati għal kull isem ospitanti permezz ta’ HTTP-01 u ma jeħtieġx plugin tal-fornitur tad-DNS għal dan. Indika l-proxy lill-kontenituri tal-admin u tas-sit fuq il-port 80 u lill-API fuq il-port intern tiegħu.

Settja NESSIE_API_TRUSTED_PROXY_HOPS għall-għadd ta’ proxies quddiem l-API — 1 meta jkun hemm reverse proxy wieħed. Id-default huwa 0, li jinjora X-Forwarded-For kompletament. Din hija deċiżjoni waħda b’żewġ konsegwenzi: hija wkoll dik li tiffissa l-limiti tar-rata tal-awtentikazzjoni, għalhekk jekk tkun baxxa wisq kull klijent jaqsam il-bucket tal-proxy, u jekk tkun għolja wisq klijent jista’ jiffalsifika l-indirizz tiegħu stess. Ibda baxx u kejjel.

Li jservi kull organizzazzjoni u tim fuq is-subdominju tagħha stess huwa possibbli, iżda mhux attivat b’mod default. Jiġi kkontrollat minn NESSIE_TEAM_HOST_BASE_DOMAIN; jekk ma jkunx issettjat, it-tenanti ma jiġux instradati skont l-isem tal-ospitant, u l-gate taċ-ċertifikati NESSIE_TLS_CHECK_KEY jiċħad kollox waqt li jkun vojt — u dan huwa d-default tajjeb għal deployment li ma jużax din il-karatteristika.

Kontrolli tas-saħħa

EndpointMistoqsija li twieġeb
GET /api/healthDan il-proċess għadu ħaj? Jonqos biss ladarba jibda d-draining.
GET /api/health/readyJista’ din ir-replika tilqa’ talbiet ġodda? Dan huwa l-endpoint li għandek tindika lill-load balancer tiegħek.
GET /api/ops/healthKif qed tmur id-deployment? Rapport għal persuna — sinjali ta’ ħajja tal-worker, profondità tal-kju, xogħlijiet mejta — mhux probe.

Meta jasal SIGTERM, l-API jagħmel id-draining minflok ma jmut fejn jinsab. NESSIE_SHUTDOWN_TIMEOUT_MS jillimita dak id-draining u d-default huwa 25 sekonda; żommha taħt kull perjodu ta’ grazzja li l-orchestrator tiegħek jagħti lill-kontenitur, inkella r-runtime jtemm il-proċess qabel, u d-draining ma jibqax jiswa xejn.

L-aġġornament

Aġġornament huwa prisma migrate deploy kontra d-database eżistenti, imbagħad is-seeds, imbagħad reconcile. L-istess erba’ kmandi tal-ewwel deployment.

It-triq hija ttestjata għar-rotta li tassew tieħu installazzjoni self-hosted, mhux kontra database ġdida: CI jirrestawra snapshot meħud għoxrin migrazzjoni wara, jgħaddih sal-aħħar migrazzjoni, jivvalida l-iskema u jagħmel smoke check fuq it-tabelli ewlenin. Kull rilaxx f’dik it-tieqa ta’ wara huwa sors ta’ aġġornament ippruvat. Il-folders tal-migrazzjonijiet huma immutabbli ladarba jiġu kkummessi, u step tal-lint jfalli l-bini jekk wieħed jiġi rrinominat, innumerat mill-ġdid, imħassar jew modifikat, għax dawk kollha jkissru migrate deploy għal database li diġà rreġistrat l-ringiela l-qadima.

Migrazzjoni waħda li tfalli żżomm kull deployment wara din. migrate deploy jieqaf fl-ewwel falliment u jirrifjuta kull migrazzjoni sussegwenti b’P3009, għalhekk l-installazzjoni tibqa’ fuq ir-rilaxx il-qadim sakemm xi ħadd ineħħiha manwalment. Id-deployment tal-produzzjoni tal-proġett innifsu qatta’ ġurnata jirrifjuta kull deployment b’dan il-mod. Biex tneħħi waħda minnhom, ikkonferma li l-migrazzjoni li fallet verament għamlet rollback — l-ebda oġġett li tipproduċi m’għandu jeżisti, u dak kollu li tbiddel għandu jibqa’ fil-forma oriġinali tiegħu — u mbagħad issolvieha bħala rolled back. Migrazzjoni applikata għal nofs mhijiex kandidata.

Il-backup u r-restore għad-deployment self-hosted bil-Compose mhumiex iddokumentati fir-repożitorju, għalhekk din il-paġna ma tiddeskrivix proċedura għalihom.

Magna waħda, jew cloud ġestit

It-triq single-host bil-Docker Compose hija dik provata: hija dik li tħaddem il-produzzjoni tal-proġett innifsu, fuq server wieħed, bid-database, il-ħażna tal-oġġetti, l-API, il-worker, l-admin u s-sit bħala kontenituri wara reverse proxy kondiviż.

Li tiskala lil hinn minn magna waħda tbiddel tliet affarijiet, u kollha huma mharsa, mhux biss mogħtija bħala parir. Barra mill-modalità local, Nessie iħaddem l-API u l-worker bħala proċessi separati, u bħala kopji multipli ta’ kull wieħed, għalhekk kull kapaċità li tassumi li proċess wieħed jikkontrolla d-disk tal-magna tiġi rrifjutata: ħażna tal-oġġetti fuq fajls (falliment fl-istart), mudelli tal-ambjent tal-eżekuzzjoni bil-provider docker (inerti, u l-provisioning jfalli b’mod ċar), u l-għodod tal-builtin file_read, file_write u file_glob (riżultat ta’ għodda li jfalli, li l-aġent jista’ jaqra). Kull rifjut isemmi s-settaġġ, il-modalità, u x’għandek tuża minflok.

Għal cloud ġestit, ir-repożitorju fih il-kodiċi Terraform f’infrastructure/terraform/ immirat lejn Google Cloud: l-API bħala Cloud Run service b’minimu ta’ istanza waħda — għax iżomm klijent persistenti tal-Postgres LISTEN u jħaddem sweeps ta’ manutenzjoni, għalhekk li tnaqqasha għal żero twaqqaf il-kunsinna f’ħin reali — il-worker bħala worker pool ta’ Cloud Run, għax ma jorbot ebda port u Service qatt ma jsir lest, job tal-migrazzjoni li kull rollout jgħaddi minnu qabel, Cloud SQL għal PostgreSQL 17, u bucket ta’ GCS li jintlaħaq permezz tal-backend kompatibbli ma’ S3.

Dik it-triq hija miktuba, mhux ittestjata fil-prattika. Ir-repożitorju jgħid dan b’mod ċar, u hekk ukoll din il-paġna: m’hemm l-ebda proġett tal-Google Cloud għaliha, xejn fil-kodiċi ma ġie ppjanat jew applikat kontra proġett reali, il-path tal-multipart upload għal GCS ma ġiex ittestjat kontra bucket reali, it-tip tar-riżors tal-worker pool mhux ivvalidat, u l-għadd ta’ hops tal-trusted proxy fiha huwa placeholder li għandu jitkejjel, mhux kejl li sar. L-admin u s-sit pubbliku m’humiex immudellati hemm xejn. Ħudha bħala bidu li trid tivverifika, mhux bħala deployment appoġġjat.

Fejn jgħix id-dejta ta’ deployment, x’iżżomm is-software u x’deliberatament ma jiżżommx, hija paġna separata: Magħmul fl-UE, u fejn tgħix id-dejta tiegħek.