Nessie uzstādīšana
Palaidiet Nessie infrastruktūrā, ko izvēlaties, no viena datora līdz pārvaldītam mākonim.
Kas nepieciešams, pirms sākat
Nessie ir pnpm monorepo ar Node pakalpojumiem un divām statiskām paketēm. Neatkarīgi no tā, kā to palaižat, vispirms ir jābūt šīm četrām lietām.
- PostgreSQL ar
pgvector. Tas nav izvēles, un to nevar aizstāt ar citu — migrācijas izpildaCREATE EXTENSION vectorun izveidovector(1024)kolonnas. Ražošanā tiek izmantotspgvector/pgvector:pg17. - Node 22 un pnpm. Katrs Dockerfile mapē
infrastructure/docker/tiek veidots uznode:22-slim, un repozitorijs savu pakotņu pārvaldnieku fiksē saknespackage.jsonfailā (pnpm@10.22.0). - Ar OpenAI saderīgs modeļa galapunkts un tam atbilstoša atslēga. Gan aģenti, gan iegulšana (embeddings) iet caur to. Skatiet tālāk sadaļu „Inferences konfigurēšana”.
- S3 saderīga objektu krātuve jebkurai izvietošanai, kas nav vietējā izstrādes vide. Augšupielādes lokālajā diskā netiek pieņemtas ārpus
localrežīma, un šis noraidījums ir palaišanas kļūda, nevis pazemināta palaišana — skatiet „Viena mašīna vai pārvaldīts mākonis”.
Docker un reversais starpniekserveris (reverse proxy) ir vajadzīgi konteineru ceļam, kas aprakstīts tālāk, un domēns ar TLS ir vajadzīgs visam, kas sasniedzams no interneta.
Aparatūras izmēri — minimālais procesors, atmiņa un diska apjoms konkrētam cilvēku skaitam — repozitorijā nekur nav norādīti, tāpēc arī šī lapa tos nenorāda.
Komponentes un to savienojums
| Komponente | Kas tā ir | Piekļuve no tīmekļa |
|---|---|---|
api/ | Fastify HTTP/WebSocket API. Katrs klients runā tikai ar to. | Jā |
worker/ | Aģentu orķestrācija un fona izpilde. Pārbauda darbu rindu; nesaista nevienu portu. | Nē |
admin/ | Produkta saskarne — statiska pakotne, ko veido Vite un pasniedz nginx. | Jā |
web/ | Publiskā vietne. Statiska, pēc izvēles un nav saistīta ar produkta darbināšanu. | Jā |
| PostgreSQL | Datubāze, darbu rinda un reāllaika kopne — visas trīs. | Nē |
| Objektu krātuve | Pielikumi, avatāri un zināšanu bāzes faili. S3 saderīga; ražošanā MinIO. | Nē |
gateway/ | Pēc izvēles push starpniekserveris APNs un FCM. Izslēgts, kamēr to tieši neieslēdzat. | Jā |
API un worker ir viens attēls. Abas pakotnes ir cieši saistītas, tāpēc Dockerfile.app veido visu komandu vienreiz, un worker konteiners komandu pārraksta uz node worker/dist/index.js. local režīmā worker konteinera nav vispār: API palaiž worker iebūvētu savā procesā.
Redis nav. Darbu rinda un reāllaika transports abi balstās uz Postgres — apzināts lēmums, nevis izlaidums. Google Cloud koks dzēš savus Pub/Sub un Redis moduļus tā paša iemesla dēļ.
Porti
Vietējā izstrādē API pēc noklusējuma ir uz 5454, bet admin uz 5455.Repozitorija kopija var izmantot savu portu pāri, iestatot NESSIE_API_PORT un NESSIE_ADMIN_PORT vidē vai repozitorija .env failā; visi repozitorija rīki, tostarp pārlūka testu komplekti, nolasa tās pašas divas vērtības. Izvēlieties pāri pirms palaišanas un paturiet to: ja darbojošos pakalpojumu pārvieto uz citu portu, admin sāk sarunāties ar nepareizo API.
Ražošana ir cits jautājums, un iepriekšējais noteikums uz to neattiecas. API konteiners iekšēji klausās uz 5554 (fiksēts ar NESSIE_API_PORT), bet push starpniekserveris — uz 5556; abi atrodas aiz reversā starpniekservera.
Darbināšana vienā mašīnā izstrādei
Repozitorijs piegādā Compose failu, kurā ir tikai datubāze, un tas ir viss, kas vajadzīgs vietējai izstrādes darba plūsmai.
pnpm install
docker compose -f infrastructure/compose/docker-compose.yml up -d postgresŠis konteiners publicē Postgres uz 55432, un lietotājs, parole un datubāze visi ir nosaukti nessie. Ievietojiet savienojuma virkni .env failā repozitorija saknē — API izstrādes skripts to nolasa — un pēc tam vienreiz izpildiet migrācijas un izveidojiet worker, jo lokālajā režīmā API ielādē worker no tā būvētā dist:
DATABASE_URL=postgresql://nessie:nessie@localhost:55432/nessie
pnpm --filter @nessie/api prisma:migrate:deploy
pnpm --filter @nessie/worker build
pnpm devpnpm dev palaiž API un admin paralēli ar karsto pārlādi, uz 5454 un 5455. Pārbaudiet, vai API atbildēja uz GET /api/health.
Postgres un pgvector prasība
Trīs paplašinājumus izveido pašas migrācijas — vector, pg_trgm un pgcrypto, tāpēc lomai, kas tās izpilda, jābūt atļautai paplašinājumu izveidei. Pārvaldītā Postgres gadījumā tieši to vispirms vajag pārbaudīt.
Vektora platums ir daļa no shēmas, nevis iestatījums. thoughts.embedding, thought_recalls.query_embedding un knowledge_page_chunks.embedding ir vector(N) kolonnas, un N ir norādīts vienreiz kā EMBEDDING_DIMENSIONS failā packages/schemas/src/embedding.ts — pašlaik 1024, dabiskais platums iegulšanas modelim, ko izmanto ražošana. Katrs iegulšanas pieprasījums nosūta šo platumu, tāpēc nodrošinātājs, kas atbildētu ar citu, neizdodas skaļi, nevis ieraksta vektorus, ko datubāze noraida. Pāreja uz iegulšanas modeli citā platumā nozīmē šīs konstantes maiņu, migrācijas rakstīšanu, kas pārtipizē trīs kolonnas, un atkārtotu iegulšanu: dažādu platumu vektorus nevar pārvērst, tāpēc migrācija tos nullē, nevis saīsina.
Ja Nessie darbināt blakus citām lietojumprogrammām kopīgā Docker tīklā, dodiet tā datubāzes konteineram atšķirīgu nosaukumu. Projekta paša Compose servisa nosaukums ir nessie-postgres, nekad postgres, jo servisa nosaukums kļūst par DNS aizstājvārdu kopīgajā tīklā, un sadursme liek postgres:5432 cikliski pārslēgties starp divām datubāzēm.
Konfigurācija
Izpildlaika konfigurācija ir slāņota: fails nessie.config.json tiek montēts API un worker tikai lasīšanai, un virs tā ir vides mainīgie. Atbilstību starp abiem nosaka ConfigEnvMap pakotnē packages/config, kas ir autoritatīvais saraksts.
NESSIE_MODE izvēlas izvietošanas veidu: local (noklusējums un izstrādātāju ceļš), hosted vai selfHosted — to iestata pašizvietota instalācija. Tas atspējo izstrādes pieteikšanos un prasa CORS atļauto izcelsmju sarakstu.
Šie ir iestatījumi, bez kuriem selfHosted izvietojums neizsāksies vai nedarbosies:
| Mainīgais | Kāpēc |
|---|---|
DATABASE_URL / NESSIE_DB_URL | Postgres savienojuma virkne. |
NESSIE_AUTH_SECRET | 32 baiti heksadecimālā formātā (openssl rand -hex 32). Paraksta sesijas un sākotnējās iestatīšanas pilnvaras. Startēšana bez tā neizdodas ārpus local režīma, un tai jābūt vienādai katrā replikā un visos izlaidumos, citādi katra sesija beidzas pie katra izlaiduma. |
NESSIE_ENCRYPTION_KEY_RING, NESSIE_ENCRYPTION_ACTIVE_KEY_VERSION | JSON atslēgu gredzens un etiķete, kas izvēlas aktīvo sakni; nepieciešams ārpus local režīma. Tā ir atsevišķa sakne no paraksta noslēpuma — gredzens šifrē katru noturīgo noslēpumu, ko Nessie glabā. Neizmantojiet vienu kā otru. |
NESSIE_STORAGE_PROVIDER | Jābūt s3. filesystem ir noklusējums, un to noraida režīmos hosted un selfHosted, tāpēc izvietojums, kas šeit neko neiestata, neizsāksies, nevis rakstīs augšupielādes diskā, kuram neviens cits konteiners nepiekļūst. |
NESSIE_CORS_ORIGINS | Admin izcelsme. Admin un API ir atsevišķas izcelsmes, un API jāieraksta savā atļauto izcelsmju sarakstā to, kuru tas apkalpo. |
NESSIE_API_PUBLIC_URL, NESSIE_ADMIN_PUBLIC_URL | Izmanto, lai veidotu OAuth pāradresācijas URI ārpus HTTP pieprasījuma. API pieprasījuma laikā met kļūdu, ja nav pirmā. |
NESSIE_MODEL_PROVIDER, _BASE_URL, _API_KEY | Kur iet inference. Skatiet zemāk. |
infrastructure/compose/.env.prod.example satur precīzu visu iestatījumu formātu, ar pēc izvēles blokiem — objektu krātuve, noslēpumu glabātuve, SSO, saistītais pasts — komentētiem savās vietās. Pilnais katalogs, ieskaitot katru pēc izvēles iestatījumu, ir docs/deployment/configuration.md.
Izvietošana ar Docker Compose
Nokopējiet .env.prod.example uz .env blakus docker-compose.prod.yml un aizpildiet to, pēc tam palaidiet datubāzi, veidojiet, migrējiet un startējiet. Secība ir svarīga: migrācijas un sēklas (seeds) tiek izpildītas pret jau darbojošos datubāzi, pirms kāds serviss apkalpo.
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 -dRažošanas Dockerfile pirms katras pakotnes veidošanas izpilda tās lint, tāpēc lint kļūda ir veidošanas kļūda.
Saskaņošanas solis nav izvēles
reconcile sēj katras organizācijas noklusējuma politikas noteikumus un atjauno aizsargāto MCP un Personal Assistant rīku piešķīrumus. API to agrāk darīja startējot katrā replikā; tagad tas tikai pieslēdzas, klausās un neko citu nedara, tātad bez šā soļa pirmajai organizācijai nav politikas noteikumu, un katrs aģenta piesaistes mēģinājums tiek noraidīts. Tas ir idempotents, tāpēc izpildīt to katrā izvietošanā nemaksā neko — un atjauninājums, kas uzstādīts ar roku, arī to jāizpilda.
Pirmais īpašnieka konts
Jaunai selfHosted instalācijai nav lietotāju, tāpēc API izveido vienreizēju sākotnējās iestatīšanas pilnvaru un ieraksta iestatīšanas URL žurnālā. Pilnvara glabājas Postgres, nevis procesā, tāpēc katrs replika par to vienojas.
docker compose -f infrastructure/compose/docker-compose.prod.yml logs nessie-api 2>&1 | grep bootstrapAtveriet https://<your-admin-host>/bootstrap?token=<token> un izveidojiet īpašnieka kontu. Pilnvara beidzas pēc 15 minūtēm; lai izveidotu jaunu, restartējiet API pakalpojumu.
Ja konfigurējat SSO, sākotnējās iestatīšanas solis nav vispār. Sākotnējās iestatīšanas režīms tiek apslāpēts brīdī, kad ir ieslēgts ārējais autentifikācijas nodrošinātājs — citādi tas nolaupītu pieteikšanās ekrānu —, un pirmā persona, kas pieslēdzas caur SSO, izveido noklusējuma komandu un kļūst par tās īpašnieku.
Inferences konfigurēšana
Tērzēšana ir saderīga ar OpenAI. NESSIE_MODEL_BASE_URL ir galapunkts, NESSIE_MODEL_API_KEY ir bearer atslēga, un NESSIE_MODEL_PROVIDER nosauc adapteri — Nessie kompilē adapterus openai, kimi un deepseek, un visu pārējo sasniedz caur vispārīgo ar OpenAI saderīgo savienotāju. NESSIE_MODEL_NAME nosaka izvietojuma noklusējuma modeli, kuru pārspēj katra aģenta pašas modeļa izvēle.
Iegulšana (embeddings) tiek maršrutēta atsevišķi, jo tērzēšanas nodrošinātājs to var nesniegt vispār — piemēram, DeepSeek nav iegulšanas galapunkta. Katrs neiestatīts lauks NESSIE_EMBEDDING_* manto tērzēšanas nodrošinātāju, tāpēc izvietojums, kas neiestata nevienu, iegulst caur tērzēšanas galapunktu. Iestatiet NESSIE_EMBEDDING_PROVIDER, NESSIE_EMBEDDING_MODEL un, uz starpniekservera, kas maršrutē pēc servisa, servisa segmentu, ja tērzēšanas nodrošinātājs nevar iegult. Ja to izdarīt nepareizi, neizdodas klusi, nevis skaļi: atmiņas atsaukšana un zināšanu bāzes meklēšana pāriet uz leksisko kanālu un turpina darbu, žurnālā reģistrējot kb_search: query embedding failed.
Nessie pašas izdevumu uzskaite — katras organizācijas marķieru virsgrāmata un budžeta vārti — nav atkarīga no tā, uz kuru galapunktu jūs to norādāt, un darbojas vienādi neatkarīgi no tā, vai ir konfigurēta parakstīta katra izsaukuma atribūcija.
Pieteikšanās
Nessie autentificē cilvēkus caur UnlikeOtherAI, kas pārvalda arī organizācijas un komandu struktūru. Admin pieteikšanās lapā ir viena poga „Pieteikties / Reģistrēties”.
Integrācija ir config-JWT plūsma, nevis standarta OIDC: API pasniedz parakstītu RS256 konfigurācijas dokumentu adresē GET /api/auth/sso/config un atbilstošo JWKS adresē GET /.well-known/jwks.json, abas API saimniekā. Tās uzstādīšana ir vienreizēja secība — ģenerējiet RSA-2048 atslēgu pāri un iestatiet UOA_CONFIG_JWT_PRIVATE_KEY_B64, UOA_CONFIG_JWT_KID, UOA_DOMAIN, UOA_CONFIG_URL, UOA_JWKS_URL, UOA_REDIRECT_URL un UOA_CONTACT_EMAIL; vienreiz noklikšķiniet pogu, kas izveido integrācijas pieprasījumu; pieprasījumu apstipriniet, kas uz kontaktadresi nosūta vienreizēju saiti ar klienta noslēpumu; iestatiet UOA_CLIENT_SECRET un restartējiet API. kid katram domēnam jābūt unikālam.
Novietošana aiz domēna ar TLS
Izvietojums apkalpo trīs vārdus: publisko vietni, admin un API. Admin un API izcelsmes nav savstarpēji aizstājamas. Dockerfile.admin paketē iebūvē VITE_API_BASE_URL būvēšanas laikā, tāpēc katrs būvētais admin artefakts — ieskaitot darbvirsmas būvējumu, kas to ietver — jāveido pret API izcelsmi. Ja to veidojat pret admin pašas izcelsmi, /api/auth/providers atrisinās uz admin HTML čaulu, un pieteikšanās paliks iestrēgusi pie „Notiek nodrošinātāju ielāde...”.
Ražošanā TLS beidzas pie Caddy, kas iegūst sertifikātus katram saimniekvārdam caur HTTP-01 un tam nav vajadzīgs DNS nodrošinātāja spraudnis. Norādiet starpniekserveri uz admin un vietnes konteineriem portā 80 un uz API tā iekšējā portā.
Iestatiet NESSIE_API_TRUSTED_PROXY_HOPS uz starpniekserveru skaitu API priekšā — 1 aiz viena reversā starpniekservera. Noklusējums ir 0, kas pilnībā ignorē X-Forwarded-For. Šis ir viens lēmums ar divām sekām: tas arī nosaka autentifikācijas ātruma ierobežojumu atslēgu, tāpēc, ja tas ir par zemu, katrs klients dalās ar starpniekservera kopu, un, ja par augstu, klients var viltot savu adresi. Kļūdieties uz zemāku pusi un izmēriet to.
Katras organizācijas un komandas apkalpošana savā apakšdomēnā ir iespējama un pēc noklusējuma izslēgta. To regulē NESSIE_TEAM_HOST_BASE_DOMAIN: ja tas nav iestatīts, nomnieki netiek maršrutēti pēc saimniekvārda vispār, un sertifikātu izsniegšanas vārti NESSIE_TLS_CHECK_KEY noraida visu, kamēr tas nav iestatīts — kas ir pareizs noklusējums izvietojumam, kas šo funkciju neizmanto.
Veselības pārbaudes
| Galapunkts | Jautājums, uz kuru tas atbild |
|---|---|
GET /api/health | Vai šis process ir dzīvs? Neizdodas tikai tad, kad tas ir sācis iztukšošanu (drain). |
GET /api/health/ready | Vai šī replika var pieņemt jaunus pieprasījumus? Šo vajag norādīt slodzes sadalītājam. |
GET /api/ops/health | Kā klājas izvietojumam? Pārskats cilvēkam — worker pulsa signāli, rindas dziļums, nederīgie darbi — nevis zonde. |
Uz SIGTERM API veic iztukšošanu, nevis nomirst uz vietas. NESSIE_SHUTDOWN_TIMEOUT_MS ierobežo šo iztukšošanu, un noklusējums ir 25 sekundes; turiet to zem gracijas perioda, ko jūsu orķestrators dod konteinerim, citādi izpildlaiks procesu nogalina pirms tam, un iztukšošana neko nedod.
Jaunināšana
Jaunināšana ir prisma migrate deploy pret esošo datubāzi, pēc tam sēklas, pēc tam reconcile. Tās pašas četras komandas, kas pirmajā izvietošanā.
Ceļš ir pārbaudīts tam maršrutam, ko patiesi izvēlas pašizvietotājs, nevis pret jaunu datubāzi: CI atjauno momentuzņēmumu, kas uzņemts divdesmit migrācijas aiz, migrē to līdz pašreizējai galvai, validē shēmu un izpilda pārbaudi pār galvenajām tabulām. Jebkurš izlaidums šajā pēdējā logā ir pierādīts jaunināšanas avots. Migrāciju mapes pēc iesniegšanas ir nemainīgas, un lint solis neizdodas būvēšanā, ja kāda tiek pārdēvēta, pārnumurēta, dzēsta vai mainīta, jo visas četras darbības sabojā migrate deploy datubāzei, kas jau ierakstījusi veco rindu.
Viena neizdevusies migrācija aptur katru izvietošanu pēc tās. migrate deploy apstājas pie pirmās kļūmes un noraida katru vēlāku migrāciju ar P3009, tāpēc instalācija paliek uz vecā izlaiduma, līdz kāds to notīra ar roku. Pašas projekta ražošana vienu dienu noraidīja katru izvietošanu šādā veidā. To notīrīt nozīmē apstiprināt, ka neizdevusies migrācija patiesi tika atcelta — nevienam tās izveidotajam objektam nevajadzētu eksistēt, un viss, ko tā mainīja, joprojām būtu sākotnējā formā — un tikai tad atzīmēt to kā atceltu. Migrācija, kas daļēji pielietota, nav kandidāts.
Dublēšana un atjaunošana pašizvietotajai Compose izvietošanai repozitorijā nav dokumentēta, tāpēc šī lapa nesniedz procedūru tai.
Viena mašīna vai pārvaldīts mākonis
Vienas servera Docker Compose ceļš, kas aprakstīts augstāk, ir tas, kas ir pierādīts: tas ir tas, ko projekta pati ražošana darbina vienā serverī, ar datubāzi, objektu krātuvi, API, worker, admin un vietni kā konteineriem aiz kopīga reversā starpniekservera.
Mērogošana pāri vienai mašīnai maina trīs lietas, un visas tās ir ieviestas, nevis tikai ieteiktas. Ārpus local režīma Nessie darbina API un worker kā atsevišķus procesus un kā vairākas katra kopijas, tāpēc jebkura spēja, kas pieņem, ka viens process pieder mašīnas diskam, tiek noraidīta: failu sistēmas objektu krātuve (palaišanas kļūda), izpildvides veidnes ar docker nodrošinātāju (neefektīvas, un nodrošināšana skaļi neizdodas) un iebūvētie rīki file_read, file_write un file_glob (neveiksmīgs rīka rezultāts, ko aģents var nolasīt). Katrs noraidījums nosauc iestatījumu, režīmu un to, ko lietot tā vietā.
Pārvaldītam mākonim repozitorijs satur Terraform koku infrastructure/terraform/, kas mērķē uz Google Cloud: API kā Cloud Run serviss ar minimumu viens instance (tam ir pastāvīgs Postgres LISTEN klients un tas veic uzturēšanas pārbaudes, tāpēc mērogošana līdz nullei aptur reāllaika piegādi), worker kā Cloud Run worker pool, jo tas nesaista portu un Service nekad nekļūtu gatavs, migrācijas darbs, kas nosaka katru izvietošanu, Cloud SQL for PostgreSQL 17 un GCS grozs, kam piekļūst caur S3 saderīgo aizmuguri.
Šis ceļš ir uzrakstīts, bet nav izmēģināts. Repozitorijs to saka skaidri, un tā arī šī lapa: Google Cloud projekts tam neeksistē, nekas kokā nav ieplānots vai pielietots pret reālu projektu, daudzdaļu augšupielādes ceļš uz GCS nav pārbaudīts pret reālu grozu, worker-pool resursa tips nav validēts, un tajā esošais uzticamā starpniekservera lēcienu skaits ir vietturis, nevis izmērīta vērtība. Admin un publiskā vietne tur nav modelēti vispār. Uztveriet to kā sākumpunktu, ko jūs pārbaudāt, nevis kā atbalstītu izvietojumu.
Kur atrodas izvietojuma dati, ko programmatūra glabā un ko tā apzināti neglabā, ir atsevišķa lapa: ražots ES, un kur atrodas jūsu dati.