nessie

Εγκατάσταση του Nessie

Εγκαταστήστε το Nessie στην υποδομή που επιλέγετε, από ένα μόνο μηχάνημα έως ένα διαχειριζόμενο cloud.

Τι χρειάζεστε πριν ξεκινήσετε

Το Nessie είναι ένα μονοκατάλογος pnpm με υπηρεσίες Node και δύο στατικά πακέτα. Όποιον τρόπο και αν το εκτελέσετε, πρέπει πρώτα να υπάρχουν αυτά τα τέσσερα.

  • PostgreSQL με pgvector. Δεν είναι προαιρετικό και δεν αντικαθίσταται — τα migrations εκτελούν CREATE EXTENSION vector και δημιουργούν στήλες vector(1024). Η παραγωγή χρησιμοποιεί το pgvector/pgvector:pg17.
  • Node 22 και pnpm. Κάθε Dockerfile μέσα στο infrastructure/docker/ χτίζεται πάνω στο node:22-slim, και το αποθετήριο καρφιτσώνει τον διαχειριστή πακέτων στο root package.json (pnpm@10.22.0).
  • Ένα τελικό σημείο μοντέλου συμβατό με OpenAI και ένα κλειδί για αυτό. Οι πράκτορες και οι ενσωματώσεις (embeddings) περνούν και τα δύο από εκεί. Δείτε το «Ρύθμιση του inference» παρακάτω.
  • Αποθηκευτικός χώρος αντικειμένων συμβατός με S3, για κάθε εγκατάσταση που δεν είναι η τοπική αναπτυξιακή. Τα uploads σε τοπικό δίσκο απορρίπτονται εκτός της λειτουργίας local, και αυτή η απόρριψη είναι αποτυχία εκκίνησης και όχι υποβαθμισμένη εκκίνηση — βλ. «Ένα μηχάνημα ή ένα διαχειριζόμενο cloud».

Το Docker και ένας αντίστροφος διακομιστής μεσολάβησης (reverse proxy) χρειάζονται για τη διαδρομή με containers που περιγράφεται παρακάτω, και ένα domain με TLS για οτιδήποτε είναι προσβάσιμο από το internet.

Το μέγεθος του υλικού — ελάχιστη CPU, μνήμη και δίσκος για έναν συγκεκριμένο αριθμό ανθρώπων — δεν αναφέρεται πουθενά στο αποθετήριο, οπότε και αυτή η σελίδα δεν το αναφέρει.

Τα συστατικά και πώς συνδέονται μεταξύ τους

ΣυστατικόΤι είναιΕισερχόμενη κίνηση
api/Το HTTP/WebSocket API του Fastify. Κάθε πελάτης επικοινωνεί μόνο με αυτό.Ναι
worker/Ενορχήστρωση πρακτόρων και εργασίες παρασκηνίου. Ελέγχει την ουρά εργασιών και δεν ανοίγει θύρα.Όχι
admin/Η διεπαφή του προϊόντος — ένα στατικό πακέτο που χτίζεται με Vite και σερβίρεται από nginx.Ναι
web/Ο δημόσιος ιστότοπος. Στατικός, προαιρετικός και άσχετος με τη λειτουργία του προϊόντος.Ναι
PostgreSQLΗ βάση δεδομένων, η ουρά εργασιών (job queue) και το realtime bus — και τα τρία μαζί.Όχι
Αποθηκευτικός χώρος αντικειμένωνΣυνημμένα, avatars και αρχεία της βάσης γνώσης. Συμβατό με S3· στην παραγωγή χρησιμοποιείται το MinIO.Όχι
gateway/Ένα προαιρετικό push relay για APNs και FCM. Είναι απενεργοποιημένο, εκτός αν το ενεργοποιήσετε συνειδητά.Ναι

Το API και το worker είναι μία εικόνα. Τα δύο πακέτα είναι στενά συνδεδεμένα, οπότε το Dockerfile.app χτίζει ολόκληρο το workspace μία φορά, και το container του worker αντικαθιστά την εντολή με node worker/dist/index.js. Στη λειτουργία local δεν υπάρχει καθόλου container worker: το API εκτελεί το worker ενσωματωμένο στη δική του διεργασία.

Δεν υπάρχει Redis. Η ουρά εργασιών και το realtime transport βασίζονται και τα δύο στο Postgres. Είναι απόφαση και όχι παράλειψη — το δέντρο για Google Cloud διαγράφει τις μονάδες Pub/Sub και Redis για τον ίδιο λόγο.

Θύρες

Στην τοπική ανάπτυξη το API βρίσκεται από προεπιλογή στη θύρα 5454 και το admin στη 5455. Ένα checkout μπορεί να πάρει το δικό του ζεύγος ορίζοντας τα NESSIE_API_PORT και NESSIE_ADMIN_PORT, στο περιβάλλον ή στο .env του αποθετηρίου· κάθε εργαλείο του αποθετηρίου, συμπεριλαμβανομένων των σουιτών δοκιμών του browser, διαβάζει τις ίδιες δύο τιμές. Επιλέξτε το ζεύγος πριν από την εκκίνηση και κρατήστε το: αν μετακινήσετε μια υπηρεσία που τρέχει σε άλλη θύρα, το admin θα μιλά με το λάθος API.

Η παραγωγή είναι διαφορετική περίπτωση και δεν επηρεάζεται από αυτόν τον κανόνα. Το container του API ακούει εσωτερικά στη θύρα 5554 (καρφιτσωμένη με NESSIE_API_PORT) και το push relay στη 5556, και τα δύο πίσω από τον αντίστροφο διακομιστή μεσολάβησης.

Εκτέλεση σε ένα μηχάνημα, για ανάπτυξη

Το αποθετήριο περιλαμβάνει ένα αρχείο Compose που περιέχει μόνο μια βάση δεδομένων, και αυτό είναι το μόνο που χρειάζεται ο τοπικός κύκλος ανάπτυξης.

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

Αυτό το container εκθέτει το Postgres στη θύρα 55432, με χρήστη, κωδικό και βάση όλα ονομασμένα nessie. Βάλτε τη συμβολοσειρά σύνδεσης σε ένα .env στη ρίζα του αποθετηρίου — το dev script του API τη διαβάζει — και μετά εφαρμόστε τα migrations και χτίστε το worker μία φορά, επειδή στη λειτουργία local το API φορτώνει το worker από το χτισμένο dist του:

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

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

Η εντολή pnpm dev εκτελεί το API και το admin παράλληλα, με hot reload, στις θύρες 5454 και 5455. Ελέγξτε ότι το API απάντησε με GET /api/health.

Postgres και η απαίτηση pgvector

Τρεις επεκτάσεις δημιουργούνται από τα ίδια τα migrations — vector, pg_trgm και pgcrypto — οπότε ο ρόλος που τα εκτελεί πρέπει να έχει δικαίωμα δημιουργίας επεκτάσεων. Σε managed Postgres, αυτό είναι το πρώτο που πρέπει να ελέγξετε.

Το πλάτος του διανύσματος είναι μέρος του σχήματος, όχι ρύθμιση. Οι στήλες thoughts.embedding, thought_recalls.query_embedding και knowledge_page_chunks.embedding είναι vector(N), και το N δηλώνεται μία φορά ως EMBEDDING_DIMENSIONS στο packages/schemas/src/embedding.ts — σήμερα 1024, το εγγενές πλάτος του μοντέλου ενσωμάτωσης που χρησιμοποιεί η παραγωγή. Κάθε αίτημα ενσωμάτωσης στέλνει αυτό το πλάτος, οπότε ένας πάροχος που θα απαντούσε με άλλο πλάτος αποτυγχάνει ρητά, αντί να γράψει διανύσματα που η βάση απορρίπτει. Η μετάβαση σε μοντέλο ενσωμάτωσης διαφορετικού πλάτους σημαίνει αλλαγή αυτής της σταθεράς, ένα migration που ξαναορίζει τους τρεις τύπους στηλών, και νέα ενσωμάτωση: διανύσματα διαφορετικών πλατών δεν μετατρέπονται, οπότε το migration τα μηδενίζει αντί να τα περικόπτει.

Αν τρέχετε το Nessie δίπλα σε άλλες εφαρμογές σε κοινό δίκτυο Docker, δώστε στο container της βάσης δεδομένων ένα διαφορετικό όνομα. Η υπηρεσία Compose του έργου λέγεται nessie-postgres και ποτέ postgres, επειδή το όνομα της υπηρεσίας γίνεται ψευδώνυμο DNS στο κοινό δίκτυο, και η σύγκρουση κάνει το postgres:5432 να εναλλάσσεται κυκλικά (round-robin) ανάμεσα σε δύο βάσεις δεδομένων.

Ρύθμιση

Η ρύθμιση του χρόνου εκτέλεσης είναι σε επίπεδα: ένα αρχείο nessie.config.json προσαρτάται μόνο για ανάγνωση στο API και στο worker, και πάνω από αυτό μπαίνουν οι μεταβλητές περιβάλλοντος. Η αντιστοίχιση ανάμεσά τους είναι το ConfigEnvMap στο packages/config, και αυτή είναι η επίσημη λίστα.

Το NESSIE_MODE καθορίζει τη μορφή της εγκατάστασης: local (η προεπιλογή και η διαδρομή του προγραμματιστή), hosted, ή selfHosted — που είναι ό,τι ορίζει μια εγκατάσταση σε δικό σας διακομιστή. Απενεργοποιεί τη σύνδεση ανάπτυξης και απαιτεί λίστα επιτρεπόμενων CORS.

Αυτές είναι οι ρυθμίσεις χωρίς τις οποίες μια εγκατάσταση selfHosted δεν θα ξεκινήσει, ή δεν θα λειτουργήσει σωστά:

ΜεταβλητήΓιατί
DATABASE_URL / NESSIE_DB_URLΗ συμβολοσειρά σύνδεσης της Postgres.
NESSIE_AUTH_SECRET32 bytes σε δεκαεξαδική μορφή (openssl rand -hex 32). Υπογράφει τις συνεδρίες και τα διακριτικά εκκίνησης. Η εκκίνηση αποτυγχάνει χωρίς αυτήν εκτός της λειτουργίας local, και πρέπει να είναι η ίδια τιμή σε κάθε replica και σε όλες τις αναπτύξεις, αλλιώς κάθε συνεδρία τερματίζεται σε κάθε κυκλοφορία.
NESSIE_ENCRYPTION_KEY_RING, NESSIE_ENCRYPTION_ACTIVE_KEY_VERSIONΈνας δακτύλιος κλειδιών σε JSON και η ετικέτα που επιλέγει την ενεργή ρίζα, απαιτούνται εκτός της λειτουργίας local. Πρόκειται για ξεχωριστή ρίζα από το μυστικό υπογραφής — ο δακτύλιος κρυπτογραφεί κάθε μόνιμο μυστικό που αποθηκεύει το Nessie. Μην χρησιμοποιείτε το ένα ως το άλλο.
NESSIE_STORAGE_PROVIDERΠρέπει να είναι s3. Το filesystem είναι η προεπιλογή και απορρίπτεται στις λειτουργίες hosted και selfHosted, οπότε μια εγκατάσταση που δεν ορίζει τίποτα εδώ αποτυγχάνει να ξεκινήσει, αντί να γράφει τα uploads σε δίσκο που κανένα άλλο container δεν μπορεί να διαβάσει.
NESSIE_CORS_ORIGINSΗ διεύθυνση του admin. Το admin και το API είναι ξεχωριστές διευθύνσεις, και το API πρέπει να επιτρέπει ρητά αυτήν που εξυπηρετεί.
NESSIE_API_PUBLIC_URL, NESSIE_ADMIN_PUBLIC_URLΧρησιμοποιείται για να δημιουργηθούν τα OAuth redirect URIs έξω από ένα αίτημα HTTP. Χωρίς το πρώτο, το API αποτυγχάνει τη στιγμή του αιτήματος.
NESSIE_MODEL_PROVIDER, _BASE_URL, _API_KEYΕκεί πηγαίνει το inference. Δείτε παρακάτω.

Το infrastructure/compose/.env.prod.example έχει ακριβώς τη μορφή όλων των ρυθμίσεων, με τα προαιρετικά μπλοκ — αποθηκευτικός χώρος αντικειμένων, secret vault, SSO, συνδεδεμένο email — σχολιασμένα στη θέση τους. Ο πλήρης κατάλογος, με κάθε προαιρετική ρύθμιση, βρίσκεται στο docs/deployment/configuration.md.

Ανάπτυξη με Docker Compose

Αντιγράψτε το .env.prod.example σε .env δίπλα στο docker-compose.prod.yml και συμπληρώστε το. Μετά ανεβάστε τη βάση, κάντε build, εφαρμόστε τα migrations και ξεκινήστε. Η σειρά έχει σημασία: τα migrations και τα seeds εκτελούνται σε βάση που είναι ήδη σε λειτουργία, πριν εξυπηρετήσει οποιαδήποτε υπηρεσία.

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

Τα Dockerfiles παραγωγής εκτελούν το lint κάθε πακέτου πριν το χτίσουν, οπότε μια αποτυχία lint είναι και αποτυχία build.

Το βήμα reconcile δεν είναι προαιρετικό

reconcile δημιουργεί (seed) τους προεπιλεγμένους κανόνες πολιτικής κάθε οργανισμού και συμπληρώνει τις χορηγήσεις εργαλείων για τα protected MCP και τον Personal Assistant. Το API το έκανε παλιά κατά την εκκίνηση σε κάθε replica· τώρα συνδέεται, ακούει και δεν κάνει τίποτα άλλο, οπότε χωρίς αυτό το βήμα ο πρώτος οργανισμός δεν έχει κανόνες πολιτικής και κάθε σύνδεση πράκτορα απορρίπτεται. Είναι ιδεοδύναμο (idempotent), οπότε η εκτέλεσή του σε κάθε ανάπτυξη δεν κοστίζει τίποτα — και μια αναβάθμιση που εφαρμόζεται με το χέρι πρέπει να το εκτελεί κι αυτή.

Ο πρώτος λογαριασμός ιδιοκτήτη

Μια νέα εγκατάσταση selfHosted δεν έχει χρήστες, οπότε το API εκδίδει ένα διακριτικό εκκίνησης (bootstrap) μίας χρήσης και καταγράφει μια διεύθυνση ρύθμισης. Το διακριτικό ζει στο Postgres και όχι σε μια διεργασία, ώστε κάθε replica να συμφωνεί για αυτό.

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

Ανοίξτε το https://<your-admin-host>/bootstrap?token=<token> και δημιουργήστε τον λογαριασμό ιδιοκτήτη. Το διακριτικό λήγει σε 15 λεπτά· για να εκδοθεί νέο, επανεκκινήστε την υπηρεσία του API.

Αν ρυθμίσετε SSO, δεν υπάρχει καθόλου βήμα εκκίνησης. Η λειτουργία εκκίνησης καταργείται τη στιγμή που ενεργοποιείται ένας εξωτερικός πάροχος ταυτοποίησης — αλλιώς θα κατελάμβανε την οθόνη σύνδεσης — και το πρώτο πρόσωπο που συνδέεται μέσω SSO δημιουργεί την προεπιλεγμένη ομάδα και γίνεται ο ιδιοκτήτης της.

Ρύθμιση του inference

Η συνομιλία είναι συμβατή με OpenAI. Το NESSIE_MODEL_BASE_URL είναι το τελικό σημείο, το NESSIE_MODEL_API_KEY είναι το bearer, και το NESSIE_MODEL_PROVIDER ονομάζει τον προσαρμογέα. Το Nessie περιλαμβάνει προσαρμογείς για τα openai, kimi και deepseek, και φτάνει σε οτιδήποτε άλλο μέσω του γενικού συνδέσμου συμβατού με OpenAI. Το NESSIE_MODEL_NAME ορίζει το προεπιλεγμένο μοντέλο της εγκατάστασης, το οποίο υπερισχύεται όμως από την επιλογή μοντέλου κάθε πράκτορα.

Οι ενσωματώσεις δρομολογούνται χωριστά, επειδή ο πάροχος της συνομιλίας μπορεί να μην παρέχει καθόλου ενσωματώσεις — το DeepSeek, για παράδειγμα, δεν έχει τελικό σημείο ενσωματώσεων. Κάθε μη ορισμένο πεδίο NESSIE_EMBEDDING_* κληρονομεί τον πάροχο της συνομιλίας, οπότε μια εγκατάσταση που δεν ορίζει κανένα από αυτά κάνει ενσωματώσεις μέσω του τελικού σημείου της συνομιλίας. Ορίστε τα NESSIE_EMBEDDING_PROVIDER, NESSIE_EMBEDDING_MODEL και, σε διακομιστή μεσολάβησης που δρομολογεί ανά υπηρεσία, το τμήμα της υπηρεσίας, όταν ο πάροχος της συνομιλίας δεν μπορεί να κάνει ενσωματώσεις. Το λάθος εδώ αποτυγχάνει σιωπηλά αντί για ορατά: η μνήμη ανάκτησης και η αναζήτηση στη βάση γνώσης υποβαθμίζονται σε λεξικό (lexical) κανάλι και συνεχίζουν, καταγράφοντας kb_search: query embedding failed.

Η λογιστική κατανάλωσης του ίδιου του Nessie — το ledger ανά οργανισμό και η πύλη προϋπολογισμού — δεν επηρεάζεται από το τελικό σημείο στο οποίο το στέλνετε, και λειτουργεί το ίδιο είτε είναι ενεργή η υπογεγραμμένη απόδοση ανά κλήση είτε όχι.

Σύνδεση

Το Nessie ταυτοποιεί τα πρόσωπα μέσω της UnlikeOtherAI, που διαχειρίζεται επίσης τη δομή οργανισμών και ομάδων. Η σελίδα σύνδεσης του admin εμφανίζει ένα μόνο κουμπί «Login / Register».

Η ενσωμάτωση είναι ροή config-JWT και όχι τυπικό OIDC: το API σερβίρει ένα υπογεγραμμένο έγγραφο ρύθμισης RS256 στο GET /api/auth/sso/config και το αντίστοιχο JWKS στο GET /.well-known/jwks.json, και τα δύο στον host του API. Η εγκατάσταση είναι μια εφάπαξ ακολουθία: δημιουργήστε ένα ζεύγος κλειδιών RSA-2048 και ορίστε τα UOA_CONFIG_JWT_PRIVATE_KEY_B64, UOA_CONFIG_JWT_KID, UOA_DOMAIN, UOA_CONFIG_URL, UOA_JWKS_URL, UOA_REDIRECT_URL και UOA_CONTACT_EMAIL· πατήστε το κουμπί μία φορά, που ανοίγει ένα αίτημα ενσωμάτωσης· περιμένετε να εγκριθεί το αίτημα, κάτι που στέλνει έναν σύνδεσμο μίας χρήσης στη διεύθυνση επικοινωνίας μαζί με το μυστικό πελάτη (client secret)· ορίστε το UOA_CLIENT_SECRET και επανεκκινήστε το API. Το kid πρέπει να είναι μοναδικό ανά domain.

Τοποθέτηση πίσω από domain, με TLS

Μια εγκατάσταση σερβίρει τρία ονόματα: τον δημόσιο ιστότοπο, το admin και το API. Τα origins του admin και του API δεν είναι εναλλάξιμα. Το Dockerfile.admin ενσωματώνει το VITE_API_BASE_URL στο bundle κατά το build, οπότε κάθε χτισμένο admin artifact — συμπεριλαμβανομένου ενός desktop build που το ενσωματώνει — πρέπει να χτίζεται με το origin του API. Αν χτιστεί με το δικό του origin του admin, το /api/auth/providers επιλύεται στο HTML του admin και η σύνδεση μένει κολλημένη στο «Loading providers...».

Η παραγωγή τερματίζει το TLS στο Caddy, που αποκτά πιστοποιητικά ανά hostname μέσω HTTP-01 και δεν χρειάζεται plugin παρόχου DNS γι' αυτό. Ορίστε τον διακομιστή μεσολάβησης να δείχνει στα containers του admin και του web στη θύρα 80, και στο API στην εσωτερική του θύρα.

Ορίστε το NESSIE_API_TRUSTED_PROXY_HOPS στον αριθμό των διακομιστών μεσολάβησης μπροστά από το API — 1 πίσω από έναν μόνο αντίστροφο διακομιστή μεσολάβησης. Η προεπιλογή είναι 0, που αγνοεί εντελώς το X-Forwarded-For. Είναι μία απόφαση με δύο συνέπειες: καθορίζει επίσης τον κάδο των ορίων αιτημάτων ταυτοποίησης, οπότε αν είναι πολύ χαμηλό, κάθε πελάτης μοιράζεται τον κάδο του διακομιστή μεσολάβησης, και αν είναι πολύ υψηλό, ένας πελάτης μπορεί να πλαστογραφήσει τη δική του διεύθυνση. Προτιμήστε χαμηλή τιμή και μετρήστε την.

Η εξυπηρέτηση κάθε οργανισμού και ομάδας στο δικό της subdomain είναι δυνατή και απενεργοποιημένη από προεπιλογή. Ρυθμίζεται από το NESSIE_TEAM_HOST_BASE_DOMAIN· αν δεν έχει οριστεί, οι tenants δεν δρομολογούνται καθόλου με βάση το hostname, και η πύλη έκδοσης πιστοποιητικών NESSIE_TLS_CHECK_KEY απορρίπτει τα πάντα όσο δεν έχει οριστεί — που είναι η σωστή προεπιλογή για μια εγκατάσταση που δεν χρησιμοποιεί αυτή τη δυνατότητα.

Έλεγχοι υγείας

Τελικό σημείοΕρώτημα που απαντά
GET /api/healthΕίναι αυτή η διεργασία ζωντανή; Αποτυγχάνει μόνο αφού ξεκινήσει το drain.
GET /api/health/readyΜπορεί αυτό το replica να δέχεται νέα αιτήματα; Αυτό είναι το σημείο στο οποίο πρέπει να δείχνει ο εξισορροπητής φορτίου.
GET /api/ops/healthΠώς τα πάει η εγκατάσταση; Μια αναφορά για άνθρωπο — heartbeats των worker, βάθος ουράς, νεκρές εργασίες — και όχι probe.

Με το SIGTERM το API ολοκληρώνει τις εργασίες του (drain) αντί να τερματιστεί αμέσως. Το NESSIE_SHUTDOWN_TIMEOUT_MS ορίζει το όριο αυτής της ολοκλήρωσης, και η προεπιλογή είναι 25 δευτερόλεπτα. Κρατήστε το κάτω από όση χάρη δίνει ο orchestrator στο container· αλλιώς το runtime τερματίζει πρώτο τη διεργασία, και η ολοκλήρωση δεν προσφέρει τίποτα.

Αναβάθμιση

Μια αναβάθμιση είναι prisma migrate deploy στην υπάρχουσα βάση, μετά τα seeds και μετά το reconcile. Οι ίδιες τέσσερις εντολές με την πρώτη ανάπτυξη.

Η διαδρομή δοκιμάζεται για τον δρόμο που πραγματικά ακολουθεί ένας self-hoster, και όχι σε καινούργια βάση: το CI επαναφέρει ένα στιγμιότυπο που λήφθηκε είκοσι migrations πίσω, το μεταφέρει στην τρέχουσα κεφαλή, επικυρώνει το σχήμα και τρέχει έναν έλεγχο καπνού στους βασικούς πίνακες. Κάθε κυκλοφορία μέσα σε αυτό το κινούμενο παράθυρο είναι αποδεδειγμένη πηγή αναβάθμισης. Οι φάκελοι migrations είναι αμετάβλητοι μόλις γίνουν commit, και ένα βήμα lint αποτυγχάνει το build αν μετονομαστεί, αλλάξει αριθμό, διαγραφεί ή τροποποιηθεί ένας από αυτούς, επειδή και τα τέσσερα σπάνε το migrate deploy για βάση που έχει ήδη καταγράψει την παλιά γραμμή.

Μία αποτυχημένη migration παγώνει κάθε ανάπτυξη μετά από αυτήν. Το migrate deploy σταματά στην πρώτη αποτυχία και αρνείται κάθε μεταγενέστερη migration με P3009, οπότε η εγκατάσταση μένει στην παλιά κυκλοφορία μέχρι να την καθαρίσει κάποιος με το χέρι. Η δική της παραγωγή του έργου πέρασε μια μέρα απορρίπτοντας κάθε ανάπτυξη με αυτόν τον τρόπο. Για να καθαριστεί, βεβαιωθείτε ότι η αποτυχημένη migration πράγματι έκανε rollback — κανένα από τα αντικείμενα που δημιουργεί δεν πρέπει να υπάρχει, και ό,τι τροποποιεί πρέπει να έχει ακόμα την αρχική του μορφή — και μόνο τότε επιλύστε την ως rolled back. Μια migration που εφαρμόστηκε στη μέση δεν είναι υποψήφια.

Το backup και η επαναφορά για την εγκατάσταση με Docker Compose σε δικό σας διακομιστή δεν τεκμηριώνονται στο αποθετήριο, οπότε αυτή η σελίδα δεν περιγράφει διαδικασία γι' αυτό.

Ένα μηχάνημα ή ένα διαχειριζόμενο cloud

Η διαδρομή με Docker Compose σε έναν μόνο κόμβο που περιγράφεται παραπάνω είναι η αποδεδειγμένη: είναι ακριβώς ό,τι τρέχει η δική της παραγωγή του έργου, σε έναν διακομιστή, με τη βάση δεδομένων, το object storage, το API, το worker, το admin και τον ιστότοπο ως containers πίσω από έναν κοινό αντίστροφο διακομιστή μεσολάβησης.

Η κλιμάκωση πέρα από ένα μηχάνημα αλλάζει τρία πράγματα, και όλα επιβάλλονται αντί να συνιστώνται. Εκτός της λειτουργίας local, το Nessie τρέχει το API και το worker ως ξεχωριστές διεργασίες, και ως πολλά αντίγραφα του καθενός, οπότε κάθε δυνατότητα που υποθέτει ότι μία διεργασία κατέχει τον δίσκο του μηχανήματος απορρίπτεται: το object storage σε filesystem (αποτυχία εκκίνησης), τα πρότυπα περιβάλλοντος εκτέλεσης με τον πάροχο docker (αδρανή, και η παροχή αποτυγχάνει ρητά), και τα ενσωματωμένα εργαλεία file_read, file_write και file_glob (αποτυχημένο αποτέλεσμα εργαλείου που μπορεί να διαβάσει ο πράκτορας). Κάθε άρνηση ονομάζει τη ρύθμιση, τη λειτουργία και το τι να χρησιμοποιήσετε αντί αυτής.

Για διαχειριζόμενο cloud, το αποθετήριο περιέχει ένα δέντρο Terraform στο infrastructure/terraform/ που στοχεύει το Google Cloud: το API ως υπηρεσία Cloud Run με ελάχιστο ένα instance — κρατά έναν μόνιμο client LISTEN στο Postgres και εκτελεί συντηρήσεις, οπότε η κλιμάκωση στο μηδέν σταματά την παράδοση σε πραγματικό χρόνο — το worker ως Cloud Run worker pool, επειδή δεν ανοίγει θύρα και μια Service δεν θα γινόταν ποτέ έτοιμη, μια εργασία migrate που ελέγχει κάθε κυκλοφορία, Cloud SQL για PostgreSQL 17, και ένα bucket GCS προσπελάσιμο μέσω του S3-συμβατού backend.

Αυτή η διαδρομή είναι γραμμένη, όχι δοκιμασμένη. Το αποθετήριο το λέει καθαρά, και το ίδιο κάνει αυτή η σελίδα: δεν υπάρχει project του Google Cloud γι' αυτήν, τίποτα στο δέντρο δεν έχει σχεδιαστεί ή εφαρμοστεί σε πραγματικό project, η διαδρομή multipart upload προς το GCS δεν έχει δοκιμαστεί σε πραγματικό bucket, ο τύπος πόρου worker pool δεν έχει επικυρωθεί, και το πλήθος των hops του έμπιστου διακομιστή μεσολάβησης είναι placeholder που πρέπει να μετρηθεί, και όχι μέτρηση. Ο admin και ο δημόσιος ιστότοπος δεν μοντελοποιούνται καθόλου εκεί. Αντιμετωπίστε το ως αρχή που θα επαληθεύσετε, και όχι ως υποστηριζόμενη ανάπτυξη.

Πού βρίσκονται τα δεδομένα μιας ανάπτυξης, τι κρατά το λογισμικό και τι σκόπιμα δεν κρατά, είναι ξεχωριστή σελίδα: Φτιαγμένο στην ΕΕ, και πού βρίσκονται τα δεδομένα σας.