nessie

Nessie telepítése

Futtasd a Nessie-t a számodra megfelelő infrastruktúrán, egyetlen gépen vagy felügyelt felhőben.

Mire van szükség a kezdés előtt

A Nessie egy pnpm-monorepó Node-szolgáltatásokból és két statikus csomagból áll. Bárhogyan futtatod is, ugyanazt a négy dolgot kell előbb megteremteni.

  • PostgreSQL pgvector-ral. Nem opcionális, és nem helyettesíthető: a migrációk lefuttatják a CREATE EXTENSION vector parancsot, és vector(1024) típusú oszlopokat hoznak létre. Az éles környezet a pgvector/pgvector:pg17 image-et használja.
  • Node 22 és pnpm. Az infrastructure/docker/ minden Dockerfile-ja a node:22-slim-re épül, a gyökér package.json pedig rögzíti a csomagkezelőt (pnpm@10.22.0).
  • OpenAI-kompatibilis modellvégpont és hozzá tartozó kulcs. Az ügynökök és a beágyazások is ezen keresztül futnak. Lásd lentebb: „Az inferencia beállítása”.
  • S3-kompatibilis objektumtárolás, minden olyan telepítéshez, amely nem a helyi fejlesztői környezet. Feltöltést helyi lemezre a local módon kívül nem fogad el a rendszer, és ez az elutasítás indítási hiba, nem leromlott indulás – lásd: „Egy gép, vagy felügyelt felhő”.

A Docker és egy fordított proxy a lentebb leírt konténeres úthoz kell, az internetről elérhető bármihez pedig domain és TLS.

A hardverméretezés, vagyis a minimális processzor-, memória- és lemezigény adott számú emberhez, nincs leírva a tárolóban, ezért ez az oldal sem írja le.

Az összetevők és a kapcsolatuk

ÖsszetevőMi ezBejövő forgalom
api/A Fastify HTTP/WebSocket API. Minden kliens ezzel beszél, másikkal nem.Igen
worker/Az ügynökök vezénylése és a háttérfutások. A feladatsort figyeli, portot nem köt.Nem
admin/A termékfelület – a Vite által épített statikus csomag, amelyet az nginx szolgál ki.Igen
web/A nyilvános weboldal. Statikus és opcionális, a termék futtatásához nincs köze.Igen
PostgreSQLAz adatbázis, a feladatsor és a valós idejű busz – mindhárom.Nem
ObjektumtárolásMellékletek, avatarok és tudásbázis-fájlok. S3-kompatibilis; éles környezetben MinIO.Nem
gateway/Opcionális push-közvetítő az APNs és az FCM számára. Alapból ki van kapcsolva, amíg szándékosan be nem kapcsolod.Igen

Az API és a worker egy rendszerkép. A két csomag szorosan összefügg, ezért a Dockerfile.app a teljes csapatot egyszer építi meg, a worker-konténer pedig a parancsot node worker/dist/index.js-re írja felül. local módban nincs külön worker-konténer: az API a saját folyamatában futtatja a beágyazott workert.

Nincs Redis. A feladatsor és a valós idejű átvitel is Postgres-alapú. Ez tudatos döntés, nem mulasztás: a Google Cloud-fa ugyanezért törli a Pub/Sub- és Redis-moduljait.

Portok

Helyi fejlesztésben alapértelmezés szerint az API az 5454, az admin az 5455 porton fut. Egy checkout saját párost is használhat: állítsd be a NESSIE_API_PORT és a NESSIE_ADMIN_PORT értékét a környezetben vagy a repository .env fájljában; a repository minden eszköze, köztük a böngészős tesztcsomagok is, ugyanezt a két értéket olvassa. Indulás előtt válaszd ki a párost, és tartsd meg: ha egy futó szolgáltatást másik portra helyezel, az admin rossz API-val fog beszélgetni.

Az éles környezet más, és erre a szabályra nincs hatással. Az API-konténer belsőleg az 5554 porton figyel (a NESSIE_API_PORT-tal rögzítve), a push-közvetítő pedig az 5556 porton, mindkettő a fordított proxy mögött.

Futtatás egy gépen, fejlesztéshez

A repository egy Compose-fájlt tartalmaz, amelyben csak egy adatbázis van. Ez a helyi munkamenethez elég.

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

Ez a konténer a Postgres-t az 55432 porton teszi elérhetővé, a felhasználó, a jelszó és az adatbázis neve mindhárom nessie. A kapcsolati stringet a repository gyökerében lévő .env fájlba írja – az API fejlesztői szkriptje ezt olvassa –, majd lefuttatja a migrációkat, és egyszer lefordítja a workert, mert helyi módban az API a worker lefordított dist mappájából tölti be:

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

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

A pnpm dev párhuzamosan futtatja az API-t és az admint élő újratöltéssel (hot reload), az 5454-es és az 5455-ös porton. Ellenőrizd, hogy az API válaszol-e a GET /api/health hívásra.

Postgres, és a pgvector-követelmény

A migrációk maguk hozzák létre a három kiterjesztést – vector, pg_trgm és pgcrypto –, ezért annak a szerepkörnek, amely lefuttatja őket, jogosultsága kell legyen kiterjesztések létrehozására. Felügyelt Postgres esetén ezt kell először ellenőrizni.

A vektorszélesség a séma része, nem beállítás. A thoughts.embedding, a thought_recalls.query_embedding és a knowledge_page_chunks.embedding vector(N) típusú oszlopok, az N pedig egyszer van rögzítve EMBEDDING_DIMENSIONS néven, a packages/schemas/src/embedding.ts fájlban. Jelenleg ez 1024, az éles környezet beágyazási modelljének natív szélessége. Minden beágyazási kérés ezt a szélességet küldi, így az a szolgáltató, amely más szélességgel válaszolna, hangosan hibázik, ahelyett hogy olyan vektorokat írna, amelyeket az adatbázis elutasít. Más szélességű beágyazási modellre váltani azt jelenti, hogy módosítani kell ezt a konstanst, írni kell egy migrációt, amely átírja a három oszlop típusát, és újra kell beágyazni. A különböző szélességű vektorok nem konvertálhatók, ezért a migráció nullázza őket, nem csonkolja.

Ha a Nessie más alkalmazások mellett, közös Docker-hálózaton fut, adj az adatbázis-konténernek egyedi nevet. A projekt saját Compose-szolgáltatása nessie-postgres, és soha nem postgres, mert a szolgáltatásnév DNS-aliasként jelenik meg a közös hálózaton. Ütközés esetén a postgres:5432 körforgásos (round-robin) váltással két adatbázis között osztana meg a forgalmat.

Konfiguráció

A futásidejű konfiguráció rétegzett: egy csak olvasható módban az API-ba és a workerbe csatolt nessie.config.json fájl, fölötte a környezeti változókkal. A kettő közötti megfeleltetést a packages/config-beli ConfigEnvMap adja, ez a mérvadó lista.

A NESSIE_MODE választja ki a telepítés formáját: local (az alapértelmezett, és a fejlesztői út), hosted, vagy selfHosted, ezt állítja be egy önálló telepítés. Letiltja a fejlesztői bejelentkezést, és CORS-engedélylistát követel meg.

Ezek azok a beállítások, nélkül a selfHosted telepítés nem indul el, vagy nem működik:

VáltozóMiért
DATABASE_URL / NESSIE_DB_URLA Postgres kapcsolati stringje.
NESSIE_AUTH_SECRET32 bájt hexadecimálisan (openssl rand -hex 32). Ez írja alá a munkameneteket és a bootstrap-tokeneket. A local módon kívül az indulás nélküle hibával leáll, és minden replikán, valamint a kiadások között ugyanannak kell lennie, különben minden munkamenet megszakad minden kiadásnál.
NESSIE_ENCRYPTION_KEY_RING, NESSIE_ENCRYPTION_ACTIVE_KEY_VERSIONEgy JSON-kulcsgyűrű és az aktív gyökeret kijelölő címke, a local módon kívül kötelező. Ez a külön gyökér az aláíró titoktól: a kulcsgyűrű titkosítja a Nessie által tárolt összes tartós titkot. Ne használd az egyiket a másik helyett.
NESSIE_STORAGE_PROVIDERÉrtéke s3 legyen. A filesystem az alapértelmezett, de a hosted és a selfHosted módban nem fogadja el, így az a telepítés, amely itt semmit sem állít be, nem indul el, ahelyett hogy a feltöltéseket olyan lemezre írná, amelyet más konténer nem tud elérni.
NESSIE_CORS_ORIGINSAz admin origin. Az admin és az API külön origin, az API-nak fel kell sorolnia azt az origint, amelyet kiszolgál.
NESSIE_API_PUBLIC_URL, NESSIE_ADMIN_PUBLIC_URLHTTP-kérésen kívül ezekből készülnek az OAuth-átirányítási URI-k. Az első nélkül az API kérésidőben hibát dob.
NESSIE_MODEL_PROVIDER, _BASE_URL, _API_KEYIde megy az inferencia. Lásd lentebb.

Az infrastructure/compose/.env.prod.example mindegyik beállítás pontos formáját tartalmazza, az opcionális blokkokkal – objektumtárolás, titokkezelő, SSO, csatlakoztatott levelezés –, a helyükön kommentelve. A teljes lista, benne minden opcionális beállítással, a docs/deployment/configuration.md fájlban található.

Telepítés Docker Compose-zal

Másold a .env.prod.example fájlt a docker-compose.prod.yml mellé .env néven, töltsd ki, majd indítsd el az adatbázist, építs, migrálj és indíts. A sorrend számít: a migrációk és a seed-ek egy már futó adatbázison futnak le, mielőtt bármelyik szolgáltatás kiszolgálna.

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

Az éles Dockerfile-ok építés előtt lefuttatják az egyes csomagok lintjét, így egy lint-hiba build-hibát jelent.

A reconcile lépés nem opcionális

A reconcile minden szervezethez feltölti az alapértelmezett szabályzati szabályokat, és visszatölti a védett MCP- és Personal Assistant-eszköz-jogosultságokat. Az API ezt korábban minden replikán az indulásnál végezte; most már csak csatlakozik, figyel, és mást nem tesz. Ezért e lépés nélkül az első szervezetnek nincsenek szabályzati szabályai, és minden ügynök-kötés megtagadódik. A lépés idempotens, így minden telepítéskor való futtatása ingyenes, a kézzel alkalmazott frissítésnél pedig neki is le kell futnia.

Az első tulajdonos fiókja

Egy friss selfHosted telepítésben nincsenek felhasználók, ezért az API egyszer használatos bootstrap-tokent hoz létre, és beállítási URL-t naplóz. A token az adatbázisban él, nem egy folyamatban, így minden replika ugyanazt a tokent látja.

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

Nyisd meg a https://<your-admin-host>/bootstrap?token=<token> címet, és hozd létre a tulajdonosi fiókot. A token 15 perc múlva lejár; egy új token létrehozásához indítsd újra az API szolgáltatást.

Ha SSO-t állítasz be, nincs semmilyen bootstrap-lépés. A bootstrap mód abban a pillanatban megszűnik, ahogy egy külső hitelesítési szolgáltató be van kapcsolva, különben eltérítené a bejelentkező képernyőt. Az első személy, aki SSO-n keresztül bejelentkezik, létrehozza az alapértelmezett csapatot, és annak a tulajdonosa lesz.

Az inferencia beállítása

A csevegés OpenAI-kompatibilis. A NESSIE_MODEL_BASE_URL a végpont, a NESSIE_MODEL_API_KEY a bearer-token, a NESSIE_MODEL_PROVIDER pedig az adaptert nevezi meg. A Nessie openai, kimi és deepseek adaptert fordít, minden más az általános, OpenAI-kompatibilis összekötőn keresztül érhető el. A NESSIE_MODEL_NAME a telepítés alapértelmezett modelljét állítja be, amelyet az egyes ügynökök saját modellválasztása felülír.

A beágyazásokat külön irányítjuk, mert a csevegési szolgáltató nem biztos, hogy kínál őket. A DeepSeeknek például nincs beágyazási végpontja. Minden be nem állított NESSIE_EMBEDDING_* mező örökli a csevegési szolgáltatót, így az a telepítés, amely egyiket sem állítja be, a csevegési végponton keresztül ágyaz be. Ha a csevegési szolgáltató nem tud beágyazni, állítsd be a NESSIE_EMBEDDING_PROVIDER-t, a NESSIE_EMBEDDING_MODEL-t, és szolgáltatás szerint irányító proxy esetén a szolgáltatási szegmenst is. Rosszul beállítva a hiba nem hangos, hanem csendes: a memória-visszahívás és a tudásbázis-keresés lexikális keresési csatornára esik vissza, és továbbmegy, miközben a kb_search: query embedding failed bejegyzést naplózza.

A Nessie saját költségelszámolása, vagyis a szervezetenkénti tokenelszámolás és a költségkeret-kapu, független attól, melyik végpontra mutat, és ugyanúgy működik, akár van beállítva aláírt hívásonkénti azonosítás, akár nincs.

Bejelentkezés

A Nessie-be az UnlikeOtherAI-n keresztül lépnek be az emberek, amely a szervezeti és csapatstruktúrát is kezeli. Az admin bejelentkező oldalon egyetlen „Login / Register” gomb látszik.

Az integráció config-JWT folyamat, nem szabványos OIDC: az API egy aláírt RS256 konfigurációs dokumentumot ad a GET /api/auth/sso/config címen, a hozzá tartozó JWKS-t pedig a GET /.well-known/jwks.json címen, mindkettő az API gazdagépén. A beállítás egyszeri sorozat: generálj egy RSA-2048 kulcspárt, és állítsd be a UOA_CONFIG_JWT_PRIVATE_KEY_B64, UOA_CONFIG_JWT_KID, UOA_DOMAIN, UOA_CONFIG_URL, UOA_JWKS_URL, UOA_REDIRECT_URL és UOA_CONTACT_EMAIL változókat. Kattints egyszer a gombra, ami integrációs kérelmet nyit. Hagyd jóvá a kérelmet, ami egyszer használatos linket küld a kapcsolattartó címre, amely a kliens titkát tartalmazza. Állítsd be az UOA_CLIENT_SECRET-et, és indítsa újra az API-t. A kid-nek domainenként egyedinek kell lennie.

Elhelyezés domain mögött, TLS-sel

A telepítés három nevet szolgál ki: a nyilvános oldalt, az admint és az API-t. Az admin és az API origin nem cserélhető fel. A Dockerfile.admin a VITE_API_BASE_URL-t építéskor beégeti a csomagba, így minden elkészített admin-artefaktumnak, beleértve az asztali buildet, amely beágyazza, az API originre kell épülnie. Ha az admin a saját originjére épül, a /api/auth/providers az admin HTML-héjára oldódik fel, és a bejelentkezés a „Loading providers...” üzenetnél ragad.

Az éles környezetben a TLS-t a Caddy zárja le, amely domainenként kér tanúsítványt HTTP-01 kihívással, és ehhez nincs szükség DNS-szolgáltatói bővítményre. Irányítsd a proxyt az admin- és a webkonténerekre a 80-as porton, az API-ra pedig a belső portján.

Állítsd a NESSIE_API_TRUSTED_PROXY_HOPS-t az API előtt álló proxyk számára: egy fordított proxy mögött ez 1. Az alapértéke 0, ami teljesen figyelmen kívül hagyja az X-Forwarded-For fejlécet. Ez egy döntés két következménnyel: ez határozza meg a hitelesítési sebességkorlátok kulcsát is. Túl alacsonyan minden kliens a proxy keretét osztja meg, túl magasan pedig a kliens meghamisíthatja a saját címét. Inkább alacsonyan tévedj, és mérd meg.

Minden szervezet és csapat a saját aldomainjén való kiszolgálása lehetséges, de alapból ki van kapcsolva. A NESSIE_TEAM_HOST_BASE_DOMAIN szabályozza. Ha nincs beállítva, a bérlőket nem irányítja gazdagépnév alapján a rendszer, a NESSIE_TLS_CHECK_KEY tanúsítvány-kiállítási kapu pedig mindent elutasít, amíg be nincs állítva. Ez helyes alapértelmezés azoknak a telepítéseknek, amelyek nem használják ezt a funkciót.

Állapotellenőrzések

VégpontMilyen kérdésre válaszol
GET /api/healthÉletben van-e ez a folyamat? Csak akkor hibázik, ha már leállítási fázisba lépett.
GET /api/health/readyFogadhat-e új kéréseket ez a replika? Ezt kell megadni a terheléselosztónak.
GET /api/ops/healthHogy van a telepítés? Jelentés egy embernek: worker-szívverések, feladatsor-mélység, halott feladatok. Nem szonda.

SIGTERM jelre az API levezényli a leállást, ahelyett hogy azonnal meghalna. A NESSIE_SHUTDOWN_TIMEOUT_MS korlátozza ezt a leállási időt, az alapértéke 25 másodperc. Tartsd rövidebbre annál a türelmi időnél, amelyet az orchestrátor a konténernek ad, különben a futtatókörnyezet előbb öli meg a folyamatot, és a leállítás nem ér semmit.

Frissítés

A frissítés a prisma migrate deploy futtatása a meglévő adatbázison, majd a seed-ek, majd a reconcile. Ugyanaz a négy parancs, mint az első telepítésnél.

Az útvonalat úgy teszteljük, ahogy egy önálló üzemeltető valóban végigmegy rajta, nem friss adatbázison. A CI egy húsz migrációval korábbi pillanatfelvételt állít vissza, a jelenlegi főágra migrálja, ellenőrzi a sémát, és füstpróbát futtat a fő táblákon. A visszamenőleges ablakba eső bármely kiadás igazoltan frissíthető forrás. A migrációs mappák véglegesítés után megváltoztathatatlanok, és a lint-lépés meghiúsítja az építést, ha valamelyiket átnevezik, átszámozzák, törlik vagy módosítják, mert ezek mind eltörik a migrate deploy-t olyan adatbázison, amely már rögzítette a régi sort.

Egy sikertelen migráció minden utána következő telepítést megakaszt. A migrate deploy az első hibánál megáll, és a későbbi migrációkat mind elutasítja a P3009 hibával. Így a telepítés a régi kiadáson marad, amíg valaki kézzel nem tünteti el a hibát. A projekt saját éles környezete egy napon át utasított vissza minden telepítést ilyen módon. A törléshez először meg kell erősíteni, hogy a sikertelen migráció valóban visszagördült: a benne létrehozott objektumok egyike sem létezik, a módosított részek az eredeti alakjukban vannak. Csak ezután lehet visszagörgetettként megjelölni. Félig lefutott migráció nem jelölhető így.

Az önállóan telepített Docker Compose-telepítés biztonsági mentése és visszaállítása nincs leírva a tárolóban, ezért ez az oldal sem ír le hozzá eljárást.

Egy gép, vagy felügyelt felhő

A fenti egygépes Docker Compose-út az, amely bizonyított: ezen fut a projekt saját éles környezete egyetlen szerveren, az adatbázis, az objektumtárolás, az API, a worker, az admin és a weboldal konténerekként, egy közös fordított proxy mögött.

A gépen túli skálázás három dolgot változtat meg, és ezek nem tanácsok, hanem kényszerek. A local módon kívül a Nessie az API-t és a workert külön folyamatként futtatja, mindkettőből több példányban. Ezért minden olyan képesség el van utasítva, amely feltételezi, hogy egy folyamat birtokolja a gép lemezét: a fájlrendszer-alapú objektumtárolás (indítási hiba), a docker szolgáltatóval működő környezet-sablonok (inaktívak, és a kiépítés hangosan hibázik), valamint a file_read, file_write és file_glob beépített eszközök (sikertelen eszközeredmény, amelyet az ügynök el tud olvasni). Minden elutasítás megnevezi a beállítást, a módot, és azt, mit használjon helyette.

Felügyelt felhőhöz a repository az infrastructure/terraform/ alatt egy Terraform-fát tartalmaz, amely Google Cloudra céloz. Az API Cloud Run-szolgáltatásként fut, legalább egy példánnyal, mert tartós Postgres LISTEN kliens, és karbantartó sweepeket futtat, így a nullára skálázása megállítaná a valós idejű kézbesítést. A worker Cloud Run worker poolként fut, mert nem köt portot, és egy Service sosem lenne kész. Egy migrációs job minden kiadást megelőz. Van még Cloud SQL for PostgreSQL 17, és egy GCS-bucket, amelyet az S3-kompatibilis háttéren keresztül érünk el.

Ez az út meg van írva, de nincs végigjárva. A repository ezt egyértelműen kimondja, és ez az oldal is: nincs hozzá Google Cloud-projekt, a fában semmi nincs úgy megtervezve vagy alkalmazva, hogy egy valódi projekten ellenőrizték volna. A GCS-re történő többrészes feltöltési út nincs valódi bucketen tesztelve, a worker-pool erőforrástípus nincs validálva, a benne szereplő megbízható proxy hop-szám pedig helyőrző, nem mért érték. Az admin és a nyilvános weboldal ott egyáltalán nincs modellezve. Kiindulópontként kezeld, amelyet ellenőrizni kell, nem támogatott telepítésként.

Hogy egy telepítés adatai hol élnek, mit tart nyilván a szoftver, és mit szándékosan nem, azt külön oldal írja le: Az EU-ban készült, és hol vannak az adataid.